![]() |
Home | Libraries | People | FAQ | More |
Because T might be of reference
type, in the sequel, those entries whose semantic depends on T being of reference type or not will
be distinguished using the following convention:
optional<T(not
a ref)>,
the description corresponds only to the case where T
is not of reference type.
optional<T&>, the description corresponds
only to the case where T
is of reference type.
optional<T>, the description is the same for
both cases.
![]() |
Note |
|---|---|
The following section contains various |
optional<T>::optional() noexcept;
optional.
*this is uninitialized.
optional<T> def ; assert ( !def ) ;
optional<T>::optional( none_t ) noexcept;
optional uninitialized.
*this is uninitialized.
T's
default constructor is not called.
The expression boost::none
denotes an instance of boost::none_t
that can be used as the parameter.
#include <boost/none.hpp> optional<T> n(none) ; assert ( !n ) ;
optional<T(not a ref)>::optional( T const& v )
is_copy_constructible<T>::value
is true.
optional.
*this is initialized
and its value is a copy of v.
T::T( T const&
) throws.
T::T( T const&
) is called.
T::T( T const&
); in that case, this constructor
has no effect.
T v; optional<T> opt(v); assert ( *opt == v ) ;
optional<T&>::optional( T& ref )
optional.
*this is initialized
and its value is an instance of an internal type wrapping the reference
ref.
T v; T& vref = v ; optional<T&> opt(vref); assert ( *opt == v ) ; ++ v ; // mutate referee assert (*opt == v);
optional<T(not a ref)>::optional( T&& v )
is_move_constructible<T>::value
is true.
optional.
*this is initialized
and its value is move-constructed from v.
T::T( T&& )
throws.
T::T( T&& )
is called.
T::T( T&& );
in that case, the state of v
is determined by exception safety guarantees for T::T(T&&).
T v1, v2; optional<T> opt(std::move(v1)); assert ( *opt == v2 ) ;
optional<T&>::optional( T&& ref ) = delete
optional<T(not a ref)>::optional( bool condition, T const& v ) ;
optional<T&> ::optional( bool condition, T& v ) ;
optional<T(not a ref)>::optional( T const& v )
optional<T&> ::optional( T& v )
optional<T(not a ref)>::optional()
optional<T&> ::optional()
optional<T(not a ref)>::optional( optional const& rhs );
is_copy_constructible<T>::value
is true.
optional.
*this
is initialized and its value is a copy of the
value of rhs; else
*this
is uninitialized.
T::T( T const&
) throws.
T::T(T const& )
is called.
T::T( T const&
); in that case, this constructor
has no effect.
optional<T> uninit ; assert (!uninit); optional<T> uinit2 ( uninit ) ; assert ( uninit2 == uninit ); optional<T> init( T(2) ); assert ( *init == T(2) ) ; optional<T> init2 ( init ) ; assert ( init2 == init ) ;
optional<T&>::optional( optional const& rhs );
optional.
rhs
is initialized, *this
is initialized and its value is another reference to the same object
referenced by *rhs;
else *this
is uninitialized.
rhs
is initialized, both *this and *rhs will refer to the same object
(they alias).
optional<T&> uninit ; assert (!uninit); optional<T&> uinit2 ( uninit ) ; assert ( uninit2 == uninit ); T v = 2 ; T& ref = v ; optional<T> init(ref); assert ( *init == v ) ; optional<T> init2 ( init ) ; assert ( *init2 == v ) ; v = 3 ; assert ( *init == 3 ) ; assert ( *init2 == 3 ) ;
optional<T(not a ref)>::optional( optional&& rhs ) noexcept(see below);
is_move_constructible<T>::value
is true.
optional.
rhs
is initialized, *this
is initialized and its value is move constructed from rhs; else *this is uninitialized.
T::T( T&& )
throws.
noexcept is equivalent to is_nothrow_move_constructible<T>::value.
rhs
is initialized, T::T( T &&
) is called.
T::T( T&& );
in that case, rhs remains
initialized and the value of *rhs is determined by exception safety
of T::T(T&&).
optional<std::unique_ptr<T>> uninit ; assert (!uninit); optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ; assert ( uninit2 == uninit ); optional<std::unique_ptr<T>> init( std::unique_ptr<T>(new T(2)) ); assert ( **init == T(2) ) ; optional<std::unique_ptr<T>> init2 ( std::move(init) ) ; assert ( init ); assert ( *init == nullptr ); assert ( init2 ); assert ( **init2 == T(2) ) ;
optional<T&>::optional( optional && rhs );
optional.
rhs
is initialized, *this
is initialized and its value is another reference to the same object
referenced by *rhs;
else *this
is uninitialized.
rhs
is initialized, both *this and *rhs will refer to the same object
(they alias).
optional<std::unique_ptr<T>&> uninit ; assert (!uninit); optional<std::unique_ptr<T>&> uinit2 ( std::move(uninit) ) ; assert ( uninit2 == uninit ); std::unique_ptr<T> v(new T(2)) ; optional<std::unique_ptr<T>&> init(v); assert ( *init == v ) ; optional<std::unique_ptr<T>&> init2 ( std::move(init) ) ; assert ( *init2 == v ) ; *v = 3 ; assert ( **init == 3 ) ; assert ( **init2 == 3 ) ;
template<U> explicit optional<T(not a ref)>::optional( optional<U> const& rhs );
optional.
rhs
is initialized, *this
is initialized and its value is a copy of the
value of rhs converted to type T;
else *this
is uninitialized.
T::T( U const&
) throws.
T::T( U const&
) is called if rhs is initialized, which requires
a valid conversion from U
to T.
T::T( U const&
); in that case, this constructor
has no effect.
optional<double> x(123.4); assert ( *x == 123.4 ) ; optional<int> y(x) ; assert( *y == 123 ) ;
template<U> explicit optional<T(not a ref)>::optional( optional<U>&& rhs );
optional.
rhs
is initialized, *this
is initialized and its value is move-constructed from *rhs;
else *this
is uninitialized.
T::T( U&& )
throws.
T::T( U&& )
is called if rhs is
initialized, which requires a valid conversion from U
to T.
T::T( U&& );
in that case, rhs remains
initialized and the value of *rhs is determined by exception safety
guarantee of T::T( U&&
).
optional<double> x(123.4); assert ( *x == 123.4 ) ; optional<int> y(std::move(x)) ; assert( *y == 123 ) ;
template<InPlaceFactory> explicit optional<T(not a ref)>::optional( InPlaceFactory const& f );
template<TypedInPlaceFactory> explicit optional<T(not a ref)>::optional( TypedInPlaceFactory const& f );
optional with a value of T obtained from the factory.
*this is initialized
and its value is directly given from the factory
f (i.e., the value
is not copied).
T constructor called by the factory
throws.
T
constructor used by the factory; in that case, this constructor has
no effect.
class C { C ( char, double, std::string ) ; } ; C v('A',123.4,"hello"); optional<C> x( in_place ('A', 123.4, "hello") ); // InPlaceFactory used optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used assert ( *x == v ) ; assert ( *y == v ) ;
optional& optional<T>::operator= ( none_t ) noexcept;
*this is initialized destroys its contained
value.
*this is uninitialized.
optional& optional<T(not a ref)>::operator= ( T const& rhs ) ;
rhs to an optional.
*this is initialized and its value is
a copy of rhs.
T::operator=( T const&
) or T::T(T const&)
throws.
*this was initialized, T's assignment operator is used,
otherwise, its copy-constructor is used.
*this is unchanged and its value unspecified
as far as optional
is concerned (it is up to T's
operator=()).
If *this
is initially uninitialized and T's
copy constructor fails, *this is left properly uninitialized.
T x; optional<T> def ; optional<T> opt(x) ; T y; def = y ; assert ( *def == y ) ; opt = y ; assert ( *opt == y ) ;
optional<T&>& optional<T&>::operator= ( T& rhs ) ;
*this is initialized and it references
the same object referenced by rhs.
*this was initialized, it is rebound
to the new object. See here
for details on this behavior.
int a = 1 ; int b = 2 ; T& ra = a ; T& rb = b ; optional<int&> def ; optional<int&> opt(ra) ; def = rb ; // binds 'def' to 'b' through 'rb' assert ( *def == b ) ; *def = a ; // changes the value of 'b' to a copy of the value of 'a' assert ( b == a ) ; int c = 3; int& rc = c ; opt = rc ; // REBINDS to 'c' through 'rc' c = 4 ; assert ( *opt == 4 ) ;
optional& optional<T(not a ref)>::operator= ( T&& rhs ) ;
rhs to an optional.
*this is initialized and its value is
moved from rhs.
T::operator=( T&& )
or T::T(T &&)
throws.
*this was initialized, T's move-assignment operator is used,
otherwise, its move-constructor is used.
*this is unchanged and its value unspecified
as far as optional
is concerned (it is up to T's
operator=()).
If *this
is initially uninitialized and T's
move constructor fails, *this is left properly uninitialized.
T x; optional<T> def ; optional<T> opt(x) ; T y1, y2, yR; def = std::move(y1) ; assert ( *def == yR ) ; opt = std::move(y2) ; assert ( *opt == yR ) ;
optional<T&>& optional<T&>::operator= ( T&& rhs ) = delete;
optional& optional<T(not a ref)>::operator= ( optional const& rhs ) ;
T
is CopyConstructible and CopyAssignable.
Effects:
|
|
|
|
|
|
assigns |
initializes the contained value as if direct-initializing
an object of type |
|
|
destroys the contained value by calling |
no effect |
*this;
bool(rhs) == bool(*this).
*this and rhs
remains unchanged. If an exception is thrown during the call to T's copy constructor, no effect.
If an exception is thrown during the call to T's
copy assignment, the state of its contained value is as defined by
the exception safety guarantee of T's
copy assignment.
T v; optional<T> opt(v); optional<T> def ; opt = def ; assert ( !def ) ; // previous value (copy of 'v') destroyed from within 'opt'.
optional<T&> & optional<T&>::operator= ( optional<T&> const& rhs ) ;
*rhs is initialized, *this
is initialized and it references the same object referenced by *rhs;
otherwise, *this
is uninitialized (and references no object).
*this was initialized and so is *rhs,
*this
is rebound to the new object. See here
for details on this behavior.
int a = 1 ; int b = 2 ; T& ra = a ; T& rb = b ; optional<int&> def ; optional<int&> ora(ra) ; optional<int&> orb(rb) ; def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb' assert ( *def == b ) ; *def = ora ; // changes the value of 'b' to a copy of the value of 'a' assert ( b == a ) ; int c = 3; int& rc = c ; optional<int&> orc(rc) ; ora = orc ; // REBINDS ora to 'c' through 'rc' c = 4 ; assert ( *ora == 4 ) ;
optional& optional<T(not a ref)>::operator= ( optional&& rhs ) noexcept(see below);
T
is MoveConstructible
and MoveAssignable.
Effects:
|
|
|
|
|
|
assigns |
initializes the contained value as if direct-initializing
an object of type |
|
|
destroys the contained value by calling |
no effect |
*this;
bool(rhs) == bool(*this).
noexcept is equivalent to is_nothrow_move_constructible<T>::value &&
is_nothrow_move_assignable<T>::value.
*this and rhs
remains unchanged. If an exception is thrown during the call to T's move constructor, the state of
*rhs
is determined by the exception safety guarantee of T's
move constructor. If an exception is thrown during the call to T's
move-assignment, the state of **this and *rhs is determined by the exception
safety guarantee of T's move assignment.
optional<T> opt(T(2)) ; optional<T> def ; opt = def ; assert ( def ) ; assert ( opt ) ; assert ( *opt == T(2) ) ;
optional<T&> & optional<T&>::operator= ( optional<T&>&& rhs ) ;
optional<T&>::operator= ( optional<T&>
const&
rhs ).
template<U> optional& optional<T(not a ref)>::operator= ( optional<U> const& rhs ) ;
Effect:
|
|
|
|
|
|
assigns |
initializes the contained value as if direct-initializing
an object of type |
|
|
destroys the contained value by calling |
no effect |
*this.
bool(rhs) == bool(*this).
bool(*this) remains unchanged. If an exception
is thrown during the call to T's
constructor, no effect. If an exception is thrown during the call to
T's assignment, the
state of its contained value is as defined by the exception safety
guarantee of T's copy
assignment.
T v; optional<T> opt0(v); optional<U> opt1; opt1 = opt0 ; assert ( *opt1 == static_cast<U>(v) ) ;
template<U> optional& optional<T(not a ref)>::operator= ( optional<U>&& rhs ) ;
Effect:
|
|
|
|
|
|
assigns |
initializes the contained value as if direct-initializing
an object of type |
|
|
destroys the contained value by calling |
no effect |
*this.
bool(rhs) == bool(*this).
bool(*this) remains unchanged. If an exception
is thrown during the call to T's
constructor, no effect. If an exception is thrown during the call to
T's assignment, the
state of its contained value is as defined by the exception safety
guarantee of T's copy
assignment.
T v; optional<T> opt0(v); optional<U> opt1; opt1 = std::move(opt0) ; assert ( opt0 ); assert ( opt1 ) assert ( *opt1 == static_cast<U>(v) ) ;
template<class... Args> void optional<T(not a ref)>::emplace( Args...&& args );
*this is initialized calls *this = none.
Then initializes in-place the contained value as if direct-initializing
an object of type T
with std::forward<Args>(args)....
*this is initialized.
T's constructor throws.
T,
*this
is uninitialized.
T
need not be MoveConstructible
or MoveAssignable.
On compilers that do not support variadic templates, the signature
falls back to two overloads:template<class
Arg>
void emplace(Arg&& arg) and void
emplace().
On compilers that do not support rvalue references, the signature falls
back to three overloads: taking const
and non-const lvalue reference,
and third with empty function argument list.
T v; optional<const T> opt; opt.emplace(0); // create in-place using ctor T(int) opt.emplace(); // destroy previous and default-construct another T opt.emplace(v); // destroy and copy-construct in-place (no assignment called)
template<InPlaceFactory> optional<T>& optional<T(not a ref)>::operator=( InPlaceFactory const& f );
template<TypedInPlaceFactory> optional<T>& optional<T(not a ref)>::operator=( TypedInPlaceFactory const& f );
optional
with a value of T obtained
from the factory.
*this is initialized
and its value is directly given from the factory
f (i.e., the value
is not copied).
T constructor called by the factory
throws.
T
constructor used by the factory; in that case, the optional
object will be reset to be uninitialized.
void optional<T(not a ref)>::reset( T const& v ) ;
operator=
( T
const&
v)
;
void optional<T>::reset() noexcept ;
operator=(
none_t );
T const& optional<T(not a ref)>::get() const ;
T& optional<T(not a ref)>::get() ;
inline T const& get ( optional<T(not a ref)> const& ) ;
inline T& get ( optional<T(not a ref)> &) ;
*this is initialized
BOOST_ASSERT().
T const& optional<T&>::get() const ;
T& optional<T&>::get() ;
inline T const& get ( optional<T&> const& ) ;
inline T& get ( optional<T&> &) ;
*this is initialized
BOOST_ASSERT().
T const& optional<T(not a ref)>::operator*() const& ;
T& optional<T(not a ref)>::operator*() &;
*this is initialized
BOOST_ASSERT().
On compilers that do not support ref-qualifiers on member functions
these two overloads are replaced with the classical two: a const and non-const
member functions.
T v ; optional<T> opt ( v ); T const& u = *opt; assert ( u == v ) ; T w ; *opt = w ; assert ( *opt == w ) ;
T&& optional<T(not a ref)>::operator*() &&;
*this contains a value.
return std::move(*val);.
BOOST_ASSERT().
On compilers that do not support ref-qualifiers on member functions
this overload is not present.
T & optional<T&>::operator*() const& ;
T & optional<T&>::operator*() & ;
T & optional<T&>::operator*() && ;
*this is initialized
BOOST_ASSERT().
On compilers that do not support ref-qualifiers on member functions
these three overloads are replaced with the classical two: a const and non-const
member functions.
T v ; T& vref = v ; optional<T&> opt ( vref ); T const& vref2 = *opt; assert ( vref2 == v ) ; ++ v ; assert ( *opt == v ) ;
T const& optional<T>::value() const& ;
T& optional<T>::value() & ;
return bool(*this) ? *val : throw bad_optional_access();.
const
and non-const member functions.
T v ; optional<T> o0, o1 ( v ); assert ( o1.value() == v ); try { o0.value(); // throws assert ( false ); } catch(bad_optional_access&) { assert ( true ); }
T&& optional<T>::value() && ;
return bool(*this) ? std::move(*val) : throw bad_optional_access();.
template<class U> T optional<T>::value_or(U && v) const& ;
if (*this) return **this; else return
std::forward<U>(v);.
T
is not CopyConstructible or U &&
is not convertible to T,
the program is ill-formed.
const-qualified member
function. On compilers without rvalue reference support the type of
v becomes U const&.
template<class U> T optional<T>::value_or(U && v) && ;
if (*this) return std::move(**this); else return std::forward<U>(v);.
T
is not MoveConstructible
or U &&
is not convertible to T,
the program is ill-formed.
template<class F> T optional<T>::value_or_eval(F f) const& ;
T
is CopyConstructible and F models a Generator whose result type
is convertible to T.
if
(*this) return **this; else return f();.
const-qualified member
function.
int complain_and_0() { clog << "no value returned, using default" << endl; return 0; } optional<int> o1 = 1; optional<int> oN = none; int i = o1.value_or_eval(complain_and_0); // fun not called assert (i == 1); int j = oN.value_or_eval(complain_and_0); // fun called assert (i == 0);
template<class F> T optional<T>::value_or_eval(F f) && ;
T
is MoveConstructible
and F models a Generator
whose result type is convertible to T.
if
(*this) return std::move(**this); else return
f();.
T const& optional<T(not a ref)>::get_value_or( T const& default) const ;
T& optional<T(not a ref)>::get_value_or( T& default ) ;
inline T const& get_optional_value_or ( optional<T(not a ref)> const& o, T const& default ) ;
inline T& get_optional_value_or ( optional<T(not a ref)>& o, T& default ) ;
value_or() instead.
default.
T v, z ; optional<T> def; T const& y = def.get_value_or(z); assert ( y == z ) ; optional<T> opt ( v ); T const& u = get_optional_value_or(opt,z); assert ( u == v ) ; assert ( u != z ) ;
T const* optional<T(not a ref)>::get_ptr() const ;
T* optional<T(not a ref)>::get_ptr() ;
inline T const* get_pointer ( optional<T(not a ref)> const& ) ;
inline T* get_pointer ( optional<T(not a ref)> &) ;
*this is initialized, a pointer to the
contained value; else 0
(null).
*this,
so you should not hold nor delete this pointer
T v; optional<T> opt(v); optional<T> const copt(v); T* p = opt.get_ptr() ; T const* cp = copt.get_ptr(); assert ( p == get_pointer(opt) ); assert ( cp == get_pointer(copt) ) ;
T const* optional<T(not a ref)>::operator ->() const ;
T* optional<T(not a ref)>::operator ->() ;
*this is initialized.
BOOST_ASSERT().
struct X { int mdata ; } ; X x ; optional<X> opt (x); opt->mdata = 2 ;
explicit optional<T>::operator bool() const noexcept ;
get_ptr() != 0.
optional<T> def ; assert ( def == 0 ); optional<T> opt ( v ) ; assert ( opt ); assert ( opt != 0 );
bool optional<T>::operator!() noexcept ;
*this is uninitialized, true; else false.
optional<T> opt ; assert ( !opt ); *opt = some_T ; // Notice the "double-bang" idiom here. assert ( !!opt ) ;
bool optional<T>::is_initialized() const ;
explicit operator
bool ()
;
optional<T(not a ref)> make_optional( T const& v )
optional<T>(v) for the deduced
type T of v.
template<class T> void foo ( optional<T> const& opt ) ; foo ( make_optional(1+1) ) ; // Creates an optional<int>
optional<T(not a ref)> make_optional( bool condition, T const& v )
optional<T>(condition,v) for the deduced
type T of v.
optional<double> calculate_foo() { double val = compute_foo(); return make_optional(is_not_nan_and_finite(val),val); } optional<double> v = calculate_foo(); if ( !v ) error("foo wasn't computed");
bool operator == ( optional<T> const& x, optional<T> const& y );
T
shall meet requirements of EqualityComparable.
x
and y are initialized,
(*x
== *y).
If only x or y is initialized, false.
If both are uninitialized, true.
optional<T>
not containing a value is compared unequal to any optional<T> containing any value, and equal
to any other optional<T> not containing a value. Pointers
have shallow relational operators while optional
has deep relational operators. Do not use operator== directly in generic code which expect
to be given either an optional<T> or a pointer; use equal_pointees()
instead
optional<T> oN, oN_; optional<T> o1(T(1)), o1_(T(1)); optional<T> o2(T(2)); assert ( oN == oN ); // Identity implies equality assert ( o1 == o1 ); // assert ( oN == oN_ ); // Both uninitialized compare equal assert ( oN != o1 ); // Initialized unequal to initialized. assert ( o1 == o1_ ); // Both initialized compare as (*lhs == *rhs) assert ( o1 != o2 ); //
bool operator < ( optional<T> const& x, optional<T> const& y );
*x < *y shall be well-formed and its result
shall be convertible to bool.
(!y) ? false : (!x) ? true : *x <
*y.
optional<T>
not containing a value is ordered as less than any optional<T> containing any value, and equivalent
to any other optional<T> not containing a value. Pointers
have shallow relational operators while optional
has deep relational operators. Do not use operator< directly in generic code which
expect to be given either an optional<T> or a pointer; use less_pointees()
instead. T need not
be LessThanComparable. Only
single operator<
is required. Other relational operations are defined in terms of this
one. If T's operator<
satisfies the axioms of LessThanComparable (transitivity,
antisymmetry and irreflexivity), optional<T> is LessThanComparable.
optional<T> oN, oN_; optional<T> o0(T(0)); optional<T> o1(T(1)); assert ( !(oN < oN) ); // Identity implies equivalence assert ( !(o1 < o1) ); assert ( !(oN < oN_) ); // Two uninitialized are equivalent assert ( !(oN_ < oN) ); assert ( oN < o0 ); // Uninitialized is less than initialized assert ( !(o0 < oN) ); assert ( o1 < o2 ) ; // Two initialized compare as (*lhs < *rhs) assert ( !(o2 < o1) ) ; assert ( !(o2 < o2) ) ;
bool operator != ( optional<T> const& x, optional<T> const& y );
!(
x ==
y );
bool operator > ( optional<T> const& x, optional<T> const& y );
(
y <
x );
bool operator <= ( optional<T> const& x, optional<T> const& y );
!(
y <
x );
bool operator >= ( optional<T> const& x, optional<T> const& y );
!(
x <
y );
bool operator == ( optional<T> const& x, none_t ) noexcept;
bool operator == ( none_t, optional<T> const& x ) noexcept;
!x.
T
need not meet requirements of EqualityComparable.
bool operator != ( optional<T> const& x, none_t ) noexcept;
bool operator != ( none_t, optional<T> const& x ) noexcept;
!(
x ==
y );
void swap ( optional<T>& x, optional<T>& y ) ;
T shall be swappable and T shall be MoveConstructible.
Effects:
|
|
|
|
|
|
calls |
initializes the contained value of |
|
|
initializes the contained value of |
no effect |
x and y
interchanged.
swap(T&,T&)
throws. If only one is initialized, whatever T::T ( T&& )
throws.
T x(12); T y(21); optional<T> def0 ; optional<T> def1 ; optional<T> optX(x); optional<T> optY(y); boost::swap(def0,def1); // no-op boost::swap(def0,optX); assert ( *def0 == x ); assert ( !optX ); boost::swap(def0,optX); // Get back to original values boost::swap(optX,optY); assert ( *optX == y ); assert ( *optY == x );
void swap ( optional<T&>& x, optional<T&>& y ) noexcept ;
x
refers to what y referred
to before the swap (if anything). y
refers to whatever x
referred to before the swap.
T x(12); T y(21); optional<T&> opt0; optional<T&> optX (x); optional<T&> optY (y); boost::swap(optX, optY); assert (addressof(*optX) == addressof(y)); assert (addressof(*optY) == addressof(x)); boost::swap(opt0, optX); assert ( opt0 ); assert ( !optX ); assert (addressof(*opt0) == addressof(y));[endsect]