22 General utilities library [utilities]

22.5 Optional objects [optional]

22.5.3 Class template optional [optional.optional]


22.5.3.1 General [optional.optional.general]

22.5.3.2 Constructors [optional.ctor]

22.5.3.3 Destructor [optional.dtor]

22.5.3.4 Assignment [optional.assign]

22.5.3.5 Swap [optional.swap]

22.5.3.6 Iterator support [optional.iterators]

22.5.3.7 Observers [optional.observe]

22.5.3.8 Monadic operations [optional.monadic]

22.5.3.9 Modifiers [optional.mod]


22.5.3.1 General [optional.optional.general]

namespace std { template<class T> class optional { public: using value_type = T; using iterator = implementation-defined; / see [optional.iterators] using const_iterator = implementation-defined; / see [optional.iterators] / [optional.ctor], constructors constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(see below); template<class. Args> constexpr explicit optional(in_place_t, Args&&.); template<class U, class. Args> constexpr explicit optional(in_place_t, initializer_list<U>, Args&&.); template<class U = remove_cv_t<T>> constexpr explicit(see below) optional(U&&); template<class U> constexpr explicit(see below) optional(const optional<U>&); template<class U> constexpr explicit(see below) optional(optional<U>&); / [optional.dtor], destructor constexpr ~optional(); / [optional.assign], assignment constexpr optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional&); constexpr optional& operator=(optional&&) noexcept(see below); template<class U = remove_cv_t<T>> constexpr optional& operator=(U&&); template<class U> constexpr optional& operator=(const optional<U>&); template<class U> constexpr optional& operator=(optional<U>&); template<class. Args> constexpr T& emplace(Args&&.); template<class U, class. Args> constexpr T& emplace(initializer_list<U>, Args&&.); / [optional.swap], swap constexpr void swap(optional&) noexcept(see below); / [optional.iterators], iterator support constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; / [optional.observe], observers constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const &; / freestanding-deleted constexpr T& value() &; / freestanding-deleted constexpr T&& value() &&; / freestanding-deleted constexpr const T&& value() const &&; / freestanding-deleted template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&; / [optional.monadic], monadic operations template<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &; template<class F> constexpr auto and_then(F&& f) const &&; template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &; template<class F> constexpr auto transform(F&& f) const &&; template<class F> constexpr optional or_else(F&& f) &&; template<class F> constexpr optional or_else(F&& f) const &; / [optional.mod], modifiers constexpr void reset() noexcept; private: union { remove_cv_t<T> val; / exposition only }; }; template<class T> optional(T) -> optional<T>; }
An instance of optional<T> is said to contain a value when and only when its member val is active ([class.union.general]); val is referred to as its contained value.
An optional object's contained value is nested within ([intro.object]) the optional object.
A type X is a valid contained type for optional if X is an lvalue reference type or a complete non-array object type, and remove_cvref_t<X> is a type other than in_place_t or nullopt_t.
If a specialization of optional is instantiated with a type T that is not a valid contained type for optional, the program is ill-formed.
If T is an object type, T shall meet the Cpp17Destructible requirements (Table 35).
The exposition-only variable template converts-from-any-cvref is used by some constructors for optional.
template<class T, class W> constexpr bool converts-from-any-cvref = / exposition only disjunction_v<is_constructible<T, W&>, is_convertible<W&, T>, is_constructible<T, W>, is_convertible<W, T>, is_constructible<T, const W&>, is_convertible<const W&, T>, is_constructible<T, const W>, is_convertible<const W, T>>;
constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept;
Remarks: No contained value is initialized.
For every object type T these constructors are constexpr constructors ([dcl.constexpr]).
constexpr optional(const optional& rhs);
Effects: If rhs contains a value, direct-non-list-initializes val with rhs.val.
Remarks: This constructor is defined as deleted unless is_copy_constructible_v<T> is true.
If is_trivially_copy_constructible_v<T> is true, this constructor is trivial.
constexpr optional(optional&& rhs) noexcept(see below);
Effects: If rhs contains a value, direct-non-list-initializes val with std​::​move(rhs.val).
rhs.has_value() is unchanged.
Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<T>.
If is_trivially_move_constructible_v<T> is true, this constructor is trivial.
template<class. Args> constexpr explicit optional(in_place_t, Args&&. args);
Effects: Direct-non-list-initializes val with std​::​forward<Args>(args)..
Remarks: If T's constructor selected for the initialization is a constexpr constructor, this constructor is a constexpr constructor.
template<class U, class. Args> constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&. args);
Effects: Direct-non-list-initializes val with il, std​::​forward<Args>(args)..
Remarks: If T's constructor selected for the initialization is a constexpr constructor, this constructor is a constexpr constructor.
template<class U = remove_cv_t<T>> constexpr explicit(see below) optional(U&& v);
Constraints:
  • is_constructible_v<T, U> is true,
  • is_same_v<remove_cvref_t<U>, in_place_t> is false,
  • is_same_v<remove_cvref_t<U>, optional> is false, and
  • if T is cv bool, remove_cvref_t<U> is not a specialization of optional.
Effects: Direct-non-list-initializes val with std​::​forward<U>(v).
Remarks: If T's selected constructor is a constexpr constructor, this constructor is a constexpr constructor.
The expression inside explicit is equivalent to: !is_convertible_v<U, T>
template<class U> constexpr explicit(see below) optional(const optional<U>& rhs);
Constraints:
  • is_constructible_v<T, const U&> is true, and
  • if T is not cv bool, converts-from-any-cvref<T, optional<U>> is false.
Effects: If rhs contains a value, direct-non-list-initializes val with rhs.operator*().
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<const U&, T>
template<class U> constexpr explicit(see below) optional(optional<U>& rhs);
Constraints:
  • is_constructible_v<T, U> is true, and
  • if T is not cv bool, converts-from-any-cvref<T, optional<U>> is false.
Effects: If rhs contains a value, direct-non-list-initializes val with std​::​move(rhs).operator*().
rhs.has_value() is unchanged.
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<U, T>
constexpr ~optional();
Effects: If is_trivially_destructible_v<T> is false and *this contains a value, calls val.T​::​~T().
Remarks: If is_trivially_destructible_v<T> is true, then this destructor is trivial.
constexpr optional<T>& operator=(nullopt_t) noexcept;
Returns: *this.
constexpr optional<T>& operator=(const optional& rhs);
Remarks: If any exception is thrown, the result of the expression this->has_value() 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.
This operator is defined as deleted unless is_copy_constructible_v<T> is true and is_copy_assignable_v<T> is true.
If is_trivially_copy_constructible_v<T> && is_trivially_copy_assignable_v<T> && is_trivially_destructible_v<T> is true, this assignment operator is trivial.
constexpr optional& operator=(optional&& rhs) noexcept(see below);
Constraints: is_move_constructible_v<T> is true and is_move_assignable_v<T> is true.
Remarks: The exception specification is equivalent to: is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
If any exception is thrown, the result of the expression this->has_value() remains unchanged.
If an exception is thrown during the call to T's move constructor, the state of rhs.val 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 states of val and rhs.val are determined by the exception safety guarantee of T's move assignment.
If is_trivially_move_constructible_v<T> && is_trivially_move_assignable_v<T> && is_trivially_destructible_v<T> is true, this assignment operator is trivial.
template<class U = remove_cv_t<T>> constexpr optional& operator=(U&& v);
Effects: If *this contains a value, assigns std​::​forward<U>(v) to val; otherwise direct-non-list-initializes val with std​::​forward<U>(v).
Remarks: If any exception is thrown, the result of the expression this->has_value() remains unchanged.
If an exception is thrown during the call to T's constructor, the state of v is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the states of val and v are determined by the exception safety guarantee of T's assignment.
template<class U> constexpr optional<T>& operator=(const optional<U>& rhs);
Returns: *this.
Remarks: If any exception is thrown, the result of the expression this->has_value() remains unchanged.
If an exception is thrown during the call to T's constructor, the state of rhs.val is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the states of val and rhs.val are determined by the exception safety guarantee of T's assignment.
template<class U> constexpr optional<T>& operator=(optional<U>& rhs);
Returns: *this.
Remarks: If any exception is thrown, the result of the expression this->has_value() remains unchanged.
If an exception is thrown during the call to T's constructor, the state of rhs.val is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the states of val and rhs.val are determined by the exception safety guarantee of T's assignment.
template<class. Args> constexpr T& emplace(Args&&. args);
Effects: Calls *this = nullopt.
Then direct-non-list-initializes val with std​::​forward<Args>(args​)..
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous val (if any) has been destroyed.
template<class U, class. Args> constexpr T& emplace(initializer_list<U> il, Args&&. args);
Effects: Calls *this = nullopt.
Then direct-non-list-initializes val with il, std​::​forward<Args>(​args)..
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous val (if any) has been destroyed.
constexpr void swap(optional& rhs) noexcept(see below);
Effects: See Table 71.
Table 71optional​::​swap(optional&) effects [tab:optional.swap]
*this contains a value
*this does not contain a value
rhs contains a value
calls swap(val, rhs.val)
direct-non-list-initializes val with std​::​move(rhs.val), followed by rhs.val.T​::​~T(); postcondition is that *this contains a value and rhs does not contain a value
rhs does not contain a value
direct-non-list-initializes rhs.val with std​::​move(val), followed by val.T​::​~T(); postcondition is that *this does not contain a value and rhs contains a value
no effect
Remarks: The exception specification is equivalent to: is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
If any exception is thrown, the results of the expressions this->has_value() and rhs.has_value() remain unchanged.
If an exception is thrown during the call to function swap, the states of val and rhs.val are determined by the exception safety guarantee of swap for lvalues of T.
If an exception is thrown during the call to T's move constructor, the states of val and rhs.val are determined by the exception safety guarantee of T's move constructor.
using iterator = implementation-defined; using const_iterator = implementation-defined;
These types model contiguous_iterator ([iterator.concept.contiguous]), meet the Cpp17RandomAccessIterator requirements ([random.access.iterators]), and meet the requirements for constexpr iterators ([iterator.requirements.general]), with value type remove_cv_t<T>.
The reference type is T& for iterator and const T& for const_iterator.
All requirements on container iterators ([container.reqmts]) apply to optional​::​iterator and optional​::​const_iterator as well.
Any operation that initializes or destroys the contained value of an optional object invalidates all iterators into that object.
constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept;
Returns: If has_value() is true, an iterator referring to the contained value.
Otherwise, a past-the-end iterator value.
constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept;
Returns: begin() + has_value().
constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept;
Remarks: These functions are constexpr functions.
constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept;
Remarks: These functions are constexpr functions.
constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept;
Effects: Equivalent to: return std​::​move(val);
constexpr explicit operator bool() const noexcept;
Remarks: This function is a constexpr function.
constexpr bool has_value() const noexcept;
Remarks: This function is a constexpr function.
constexpr const T& value() const &; constexpr T& value() &;
Effects: Equivalent to: return has_value() ? val : throw bad_optional_access();
constexpr T&& value() &&; constexpr const T&& value() const &&;
Effects: Equivalent to: return has_value() ? std::move(val) : throw bad_optional_access();
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
Effects: Equivalent to: return has_value() ? val : static_cast<T>(std::forward<U>(v));
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
Effects: Equivalent to: return has_value() ? std::move(val) : static_cast<T>(std::forward<U>(v));

22.5.3.8 Monadic operations [optional.monadic]

template<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) const &;
Effects: Equivalent to: if (*this) { return invoke(std::forward<F>(f), val); } else { return remove_cvref_t<U>(); }
template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &&;
Effects: Equivalent to: if (*this) { return invoke(std::forward<F>(f), std::move(val)); } else { return remove_cvref_t<U>(); }
template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) const &;
Mandates: U is a valid contained type for optional.
The declaration U u(invoke(std::forward<F>(f), val)); is well-formed for some invented variable u.
[Note 1: 
There is no requirement that U is movable ([dcl.init.general]).
— end note]
Returns: If *this contains a value, an optional<U> object whose contained value is direct-non-list-initialized with invoke(std​::​forward<F>(f), val); otherwise, optional<U>().
template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &&;
Let U be remove_cv_t<invoke_result_t<F, decltype(std​::​move(val)>.
Mandates: U is a valid contained type for optional.
The declaration U u(invoke(std::forward<F>(f), std::move(val)); is well-formed for some invented variable u.
[Note 2: 
There is no requirement that U is movable ([dcl.init.general]).
— end note]
Returns: If *this contains a value, an optional<U> object whose contained value is direct-non-list-initialized with invoke(std​::​forward<F>(f), std​::​move(val); otherwise, optional<U>().
template<class F> constexpr optional or_else(F&& f) const &;
Constraints: F models invocable and T models copy_constructible.
Effects: Equivalent to: if (*this) { return *this; } else { return std::forward<F>(f)(); }
template<class F> constexpr optional or_else(F&& f) &&;
Constraints: F models invocable and T models move_constructible.
Effects: Equivalent to: if (*this) { return std::move(*this); } else { return std::forward<F>(f)(); }
constexpr void reset() noexcept;
Effects: If *this contains a value, calls val.T​::​~T() to destroy the contained value; otherwise no effect.
Postconditions: *this does not contain a value.

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant