![]() |
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::uniqye_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.
!*this
&& !rhs no effect, otherwise
bool(*this)
&& !rhs, destroys the contained value
by calling val->T::~T(), otherwise
!*this
&& bool(rhs), initializes the contained value
as if direct-initializing an object of type T
with *rhs,
otherwise
bool(*this)
&& bool(rhs)) assigns *rhs to the contained value.
*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.
!*this
&& !rhs no effect, otherwise
bool(*this)
&& !rhs, destroys the contained value
by calling val->T::~T(), otherwise
!*this
&& bool(rhs), initializes the contained value
as if direct-initializing an object of type T
with std::move(*rhs),
otherwise
bool(*this)
&& bool(rhs)) assigns std::move(*rhs) to the contained value.
*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 ) ;
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::operator=( U const& ) or T::T( U const& ) throws.
*this and rhs are initially initialized,
T's assignment
operator (from U)
is used. If *this
is initially initialized but rhs
is uninitialized, T's
destructor is called. If *this is initially uninitialized but rhs
is initialized, T's
converting constructor (from U)
is called.
*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
converting constructor fails, *this is left properly uninitialized.
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 ) ;
rhs
is initialized, *this
is initialized and its value is moved from the value of rhs; else *this is uninitialized.
T::operator=( U&& )
or T::T( U&&
) throws.
*this and rhs
are initially initialized, T's
assignment operator (from U&&) is used. If *this
is initially initialized but rhs
is uninitialized, T's
destructor is called. If *this is initially uninitialized but rhs is initialized, T's
converting constructor (from U&&) is called.
*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
converting constructor fails, *this is left properly uninitialized.
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
need not be MoveConstructible
or MoveAssignable. On
compilers that do not support variadic templates, the signature falls
back to single-argument: template<class Arg> void emplace(Arg&& arg). On compilers that do not support rvalue
references, the signature falls back to two overloads: taking const and non-const
lvalue reference.
T,
*this
is uninitialized.
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
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
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), optinal<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.
!*this
&& !rhs, no effect, otherwise
bool(*this)
&& !rhs, initializes the contained
value of rhs as
if direct-initializing an object of type T
with the expression std::move(*(*this)), followed by val->T::~T(), *this does not contain a value and
rhs contains a
value, otherwise
!*this
&& bool(rhs), initializes the contained value
of *this
as if direct-initializing an object of type T
with the expression std::move(*rhs), followed by rhs.val->T::~T(), *this contains a value and rhs does not contain a value,
otherwise
bool(*this)
&& bool(rhs)) calls swap(*(*this), *rhs).
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 );