22 General utilities library [utilities]

22.1 General [utilities.general]

This Clause describes utilities that are generally useful in C++ programs; some of these utilities are used by other elements of the C++ standard library.
These utilities are summarized in Table 61.
Table 61: General utilities library summary [tab:utilities.summary]
Subclause
Header
Utility components
<utility>
Pairs
Tuples
<tuple>
Optional objects
<optional>
Variants
<variant>
Storage for any type
<any>
Expected objects
<expected>
Fixed-size sequences of bits
<bitset>
Function objects
<functional>
Bit manipulation
<bit>

22.2 Utility components [utility]

22.2.1 Header <utility> synopsis [utility.syn]

The header <utility> contains some basic function and class templates that are used throughout the rest of the library.
// all freestanding #include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [utility.swap], swap template<class T> constexpr void swap(T& a, T& b) noexcept(see below); template<class T, size_t N> constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>); // [utility.exchange], exchange template<class T, class U = T> constexpr T exchange(T& obj, U&& new_val) noexcept(see below); // [forward], forward/move template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept; template<class T, class U> constexpr auto forward_like(U&& x) noexcept -> see below; template<class T> constexpr remove_reference_t<T>&& move(T&&) noexcept; template<class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept; // [utility.as.const], as_const template<class T> constexpr add_const_t<T>& as_const(T& t) noexcept; template<class T> void as_const(const T&&) = delete; // [declval], declval template<class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand // [utility.intcmp], integer comparison functions template<class T, class U> constexpr bool cmp_equal(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_not_equal(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_less(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_greater(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_less_equal(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_greater_equal(T t, U u) noexcept; template<class R, class T> constexpr bool in_range(T t) noexcept; // [utility.underlying], to_underlying template<class T> constexpr underlying_type_t<T> to_underlying(T value) noexcept; // [utility.unreachable], unreachable [[noreturn]] void unreachable(); // [intseq], compile-time integer sequences template<class T, T...> struct integer_sequence; template<size_t... I> using index_sequence = integer_sequence<size_t, I...>; template<class T, T N> using make_integer_sequence = integer_sequence<T, see below>; template<size_t N> using make_index_sequence = make_integer_sequence<size_t, N>; template<class... T> using index_sequence_for = make_index_sequence<sizeof...(T)>; // [pairs], class template pair template<class T1, class T2> struct pair; template<class T1, class T2, class U1, class U2, template<class> class TQual, template<class> class UQual> requires requires { typename pair<common_reference_t<TQual<T1>, UQual<U1>>, common_reference_t<TQual<T2>, UQual<U2>>>; } struct basic_common_reference<pair<T1, T2>, pair<U1, U2>, TQual, UQual> { using type = pair<common_reference_t<TQual<T1>, UQual<U1>>, common_reference_t<TQual<T2>, UQual<U2>>>; }; template<class T1, class T2, class U1, class U2> requires requires { typename pair<common_type_t<T1, U1>, common_type_t<T2, U2>>; } struct common_type<pair<T1, T2>, pair<U1, U2>> { using type = pair<common_type_t<T1, U1>, common_type_t<T2, U2>>; }; // [pairs.spec], pair specialized algorithms template<class T1, class T2, class U1, class U2> constexpr bool operator==(const pair<T1, T2>&, const pair<U1, U2>&); template<class T1, class T2, class U1, class U2> constexpr common_comparison_category_t<synth-three-way-result<T1, U1>, synth-three-way-result<T2, U2>> operator<=>(const pair<T1, T2>&, const pair<U1, U2>&); template<class T1, class T2> constexpr void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); template<class T1, class T2> constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); template<class T1, class T2> constexpr see below make_pair(T1&&, T2&&); // [pair.astuple], tuple-like access to pair template<class T> struct tuple_size; template<size_t I, class T> struct tuple_element; template<class T1, class T2> struct tuple_size<pair<T1, T2>>; template<size_t I, class T1, class T2> struct tuple_element<I, pair<T1, T2>>; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>&) noexcept; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&&) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>&) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&&) noexcept; template<class T1, class T2> constexpr T1& get(pair<T1, T2>& p) noexcept; template<class T1, class T2> constexpr const T1& get(const pair<T1, T2>& p) noexcept; template<class T1, class T2> constexpr T1&& get(pair<T1, T2>&& p) noexcept; template<class T1, class T2> constexpr const T1&& get(const pair<T1, T2>&& p) noexcept; template<class T2, class T1> constexpr T2& get(pair<T1, T2>& p) noexcept; template<class T2, class T1> constexpr const T2& get(const pair<T1, T2>& p) noexcept; template<class T2, class T1> constexpr T2&& get(pair<T1, T2>&& p) noexcept; template<class T2, class T1> constexpr const T2&& get(const pair<T1, T2>&& p) noexcept; // [pair.piecewise], pair piecewise construction struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{}; template<class... Types> class tuple; // defined in <tuple> // in-place construction struct in_place_t { explicit in_place_t() = default; }; inline constexpr in_place_t in_place{}; template<class T> struct in_place_type_t { explicit in_place_type_t() = default; }; template<class T> constexpr in_place_type_t<T> in_place_type{}; template<size_t I> struct in_place_index_t { explicit in_place_index_t() = default; }; template<size_t I> constexpr in_place_index_t<I> in_place_index{}; // nontype argument tag template<auto V> struct nontype_t { explicit nontype_t() = default; }; template<auto V> constexpr nontype_t<V> nontype{}; }

22.2.2 swap [utility.swap]

template<class T> constexpr void swap(T& a, T& b) noexcept(see below);
Constraints: is_move_constructible_v<T> is true and is_move_assignable_v<T> is true.
Preconditions: Type T meets the Cpp17MoveConstructible (Table 31) and Cpp17MoveAssignable (Table 33) requirements.
Effects: Exchanges values stored in two locations.
Remarks: The exception specification is equivalent to: is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
template<class T, size_t N> constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
Constraints: is_swappable_v<T> is true.
Preconditions: a[i] is swappable with ([swappable.requirements]) b[i] for all i in the range [0, N).
Effects: As if by swap_ranges(a, a + N, b).

22.2.3 exchange [utility.exchange]

template<class T, class U = T> constexpr T exchange(T& obj, U&& new_val) noexcept(see below);
Effects: Equivalent to: T old_val = std::move(obj); obj = std::forward<U>(new_val); return old_val;
Remarks: The exception specification is equivalent to: is_nothrow_move_constructible_v<T> && is_nothrow_assignable_v<T&, U>

22.2.4 Forward/move helpers [forward]

The library provides templated helper functions to simplify applying move semantics to an lvalue and to simplify the implementation of forwarding functions.
All functions specified in this subclause are signal-safe.
template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
Mandates: For the second overload, is_lvalue_reference_v<T> is false.
Returns: static_cast<T&&>(t).
[Example 1: template<class T, class A1, class A2> shared_ptr<T> factory(A1&& a1, A2&& a2) { return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2))); } struct A { A(int&, const double&); }; void g() { shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int& int i = 2; shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK }
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A's constructor as an rvalue.
In the second call to factory, A1 is deduced as int&, so i is forwarded to A's constructor as an lvalue.
In both cases, A2 is deduced as double, so 1.414 is forwarded to A's constructor as an rvalue.
— end example]
template<class T, class U> constexpr auto forward_like(U&& x) noexcept -> see below;
Mandates: T is a referenceable type ([defns.referenceable]).
  • Let COPY_CONST(A, B) be const B if A is a const type, otherwise B.
  • Let OVERRIDE_REF(A, B) be remove_reference_t<B>&& if A is an rvalue reference type, otherwise B&.
  • Let V be OVERRIDE_REF(T&&, COPY_CONST(remove_reference_t<T>, remove_reference_t<U>))
Returns: static_cast<V>(x).
Remarks: The return type is V.
[Example 2: struct accessor { vector<string>* container; decltype(auto) operator[](this auto&& self, size_t i) { return std::forward_like<decltype(self)>((*container)[i]); } }; void g() { vector v{"a"s, "b"s}; accessor a{&v}; string& x = a[0]; // OK, binds to lvalue reference string&& y = std::move(a)[0]; // OK, is rvalue reference string const&& z = std::move(as_const(a))[1]; // OK, is const&& string& w = as_const(a)[1]; // error: will not bind to non-const } — end example]
template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
Returns: static_cast<remove_reference_t<T>&&>(t).
[Example 3: template<class T, class A1> shared_ptr<T> factory(A1&& a1) { return shared_ptr<T>(new T(std::forward<A1>(a1))); } struct A { A(); A(const A&); // copies from lvalues A(A&&); // moves from rvalues }; void g() { A a; shared_ptr<A> sp1 = factory<A>(a); // “a'' binds to A(const A&) shared_ptr<A> sp2 = factory<A>(std::move(a)); // “a'' binds to A(A&&) }
In the first call to factory, A1 is deduced as A&, so a is forwarded as a non-const lvalue.
This binds to the constructor A(const A&), which copies the value from a.
In the second call to factory, because of the call std​::​move(a), A1 is deduced as A, so a is forwarded as an rvalue.
This binds to the constructor A(A&&), which moves the value from a.
— end example]
template<class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept;
Returns: std​::​move(x).

22.2.5 Function template as_const [utility.as.const]

template<class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
Returns: t.

22.2.6 Function template declval [declval]

The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands.
template<class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
Mandates: This function is not odr-used ([basic.def.odr]).
Remarks: The template parameter T of declval may be an incomplete type.
[Example 1: 
template<class To, class From> decltype(static_cast<To>(declval<From>())) convert(From&&); declares a function template convert which only participates in overload resolution if the type From can be explicitly converted to type To.
For another example see class template common_type ([meta.trans.other]).
— end example]

22.2.7 Integer comparison functions [utility.intcmp]

template<class T, class U> constexpr bool cmp_equal(T t, U u) noexcept;
Mandates: Both T and U are standard integer types or extended integer types ([basic.fundamental]).
Effects: Equivalent to: using UT = make_unsigned_t<T>; using UU = make_unsigned_t<U>; if constexpr (is_signed_v<T> == is_signed_v<U>) return t == u; else if constexpr (is_signed_v<T>) return t < 0 ? false : UT(t) == u; else return u < 0 ? false : t == UU(u);
template<class T, class U> constexpr bool cmp_not_equal(T t, U u) noexcept;
Effects: Equivalent to: return !cmp_equal(t, u);
template<class T, class U> constexpr bool cmp_less(T t, U u) noexcept;
Mandates: Both T and U are standard integer types or extended integer types ([basic.fundamental]).
Effects: Equivalent to: using UT = make_unsigned_t<T>; using UU = make_unsigned_t<U>; if constexpr (is_signed_v<T> == is_signed_v<U>) return t < u; else if constexpr (is_signed_v<T>) return t < 0 ? true : UT(t) < u; else return u < 0 ? false : t < UU(u);
template<class T, class U> constexpr bool cmp_greater(T t, U u) noexcept;
Effects: Equivalent to: return cmp_less(u, t);
template<class T, class U> constexpr bool cmp_less_equal(T t, U u) noexcept;
Effects: Equivalent to: return !cmp_greater(t, u);
template<class T, class U> constexpr bool cmp_greater_equal(T t, U u) noexcept;
Effects: Equivalent to: return !cmp_less(t, u);
template<class R, class T> constexpr bool in_range(T t) noexcept;
Mandates: Both T and R are standard integer types or extended integer types ([basic.fundamental]).
Effects: Equivalent to: return cmp_greater_equal(t, numeric_limits<R>::min()) && cmp_less_equal(t, numeric_limits<R>::max());
[Note 1: 
These function templates cannot be used to compare byte, char, char8_t, char16_t, char32_t, wchar_t, and bool.
— end note]

22.2.8 Function template to_underlying [utility.underlying]

template<class T> constexpr underlying_type_t<T> to_underlying(T value) noexcept;
Returns: static_cast<underlying_type_t<T>>(value).

22.2.9 Function unreachable [utility.unreachable]

[[noreturn]] void unreachable();
Preconditions: false is true.
[Note 1: 
This precondition cannot be satisfied, thus the behavior of calling unreachable is undefined.
— end note]
[Example 1: int f(int x) { switch (x) { case 0: case 1: return x; default: std::unreachable(); } } int a = f(1); // OK, a has value 1 int b = f(3); // undefined behavior — end example]

22.3 Pairs [pairs]

22.3.1 General [pairs.general]

The library provides a template for heterogeneous pairs of values.
The library also provides a matching function template to simplify their construction and several templates that provide access to pair objects as if they were tuple objects (see [tuple.helper] and [tuple.elem]).

22.3.2 Class template pair [pairs.pair]

namespace std { template<class T1, class T2> struct pair { using first_type = T1; using second_type = T2; T1 first; T2 second; pair(const pair&) = default; pair(pair&&) = default; constexpr explicit(see below) pair(); constexpr explicit(see below) pair(const T1& x, const T2& y); template<class U1 = T1, class U2 = T2> constexpr explicit(see below) pair(U1&& x, U2&& y); template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p); template<pair-like P> constexpr explicit(see below) pair(P&& p); template<class... Args1, class... Args2> constexpr pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args); constexpr pair& operator=(const pair& p); constexpr const pair& operator=(const pair& p) const; template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p); template<class U1, class U2> constexpr const pair& operator=(const pair<U1, U2>& p) const; constexpr pair& operator=(pair&& p) noexcept(see below); constexpr const pair& operator=(pair&& p) const; template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p); template<class U1, class U2> constexpr const pair& operator=(pair<U1, U2>&& p) const; template<pair-like P> constexpr pair& operator=(P&& p); template<pair-like P> constexpr const pair& operator=(P&& p) const; constexpr void swap(pair& p) noexcept(see below); constexpr void swap(const pair& p) const noexcept(see below); }; template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>; }
Constructors and member functions of pair do not throw exceptions unless one of the element-wise operations specified to be called for that operation throws an exception.
The defaulted move and copy constructor, respectively, of pair is a constexpr function if and only if all required element-wise initializations for move and copy, respectively, would be constexpr-suitable ([dcl.constexpr]).
If (is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>) is true, then the destructor of pair is trivial.
pair<T, U> is a structural type ([temp.param]) if T and U are both structural types.
Two values p1 and p2 of type pair<T, U> are template-argument-equivalent ([temp.type]) if and only if p1.first and p2.first are template-argument-equivalent and p1.second and p2.second are template-argument-equivalent.
constexpr explicit(see below) pair();
Constraints:
  • is_default_constructible_v<T1> is true and
  • is_default_constructible_v<T2> is true.
Effects: Value-initializes first and second.
Remarks: The expression inside explicit evaluates to true if and only if either T1 or T2 is not implicitly default-constructible.
[Note 1: 
This behavior can be implemented with a trait that checks whether a const T1& or a const T2& can be initialized with {}.
— end note]
constexpr explicit(see below) pair(const T1& x, const T2& y);
Constraints:
  • is_copy_constructible_v<T1> is true and
  • is_copy_constructible_v<T2> is true.
Effects: Initializes first with x and second with y.
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<const T1&, T1> || !is_convertible_v<const T2&, T2>
template<class U1 = T1, class U2 = T2> constexpr explicit(see below) pair(U1&& x, U2&& y);
Constraints:
  • is_constructible_v<T1, U1> is true and
  • is_constructible_v<T2, U2> is true.
Effects: Initializes first with std​::​forward<U1>(x) and second with std​::​forward<U2>(y).
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<U1, T1> || !is_convertible_v<U2, T2>
This constructor is defined as deleted if reference_constructs_from_temporary_v<first_type, U1&&> is true or reference_constructs_from_temporary_v<second_type, U2&&> is true.
template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p); template<pair-like P> constexpr explicit(see below) pair(P&& p);
Let FWD(u) be static_cast<decltype(u)>(u).
Constraints:
  • For the last overload, remove_cvref_t<P> is not a specialization of ranges​::​subrange,
  • is_constructible_v<T1, decltype(get<0>(FWD(p)))> is true, and
  • is_constructible_v<T2, decltype(get<1>(FWD(p)))> is true.
Effects: Initializes first with get<0>(FWD(p)) and second with get<1>(FWD(p)).
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<decltype(get<0>(FWD(p))), T1> || !is_convertible_v<decltype(get<1>(FWD(p))), T2>
The constructor is defined as deleted if reference_constructs_from_temporary_v<first_type, decltype(get<0>(FWD(p)))> || reference_constructs_from_temporary_v<second_type, decltype(get<1>(FWD(p)))> is true.
template<class... Args1, class... Args2> constexpr pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
Mandates:
  • is_constructible_v<T1, Args1...> is true and
  • is_constructible_v<T2, Args2...> is true.
Effects: Initializes first with arguments of types Args1... obtained by forwarding the elements of first_args and initializes second with arguments of types Args2... obtained by forwarding the elements of second_args.
(Here, forwarding an element x of type U within a tuple object means calling std​::​forward<U>(x).)
This form of construction, whereby constructor arguments for first and second are each provided in a separate tuple object, is called piecewise construction.
[Note 2: 
If a data member of pair is of reference type and its initialization binds it to a temporary object, the program is ill-formed ([class.base.init]).
— end note]
constexpr pair& operator=(const pair& p);
Effects: Assigns p.first to first and p.second to second.
Returns: *this.
Remarks: This operator is defined as deleted unless is_copy_assignable_v<T1> is true and is_copy_assignable_v<T2> is true.
constexpr const pair& operator=(const pair& p) const;
Constraints:
  • is_copy_assignable_v<const T1> is true and
  • is_copy_assignable_v<const T2> is true.
Effects: Assigns p.first to first and p.second to second.
Returns: *this.
template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
Constraints:
  • is_assignable_v<T1&, const U1&> is true and
  • is_assignable_v<T2&, const U2&> is true.
Effects: Assigns p.first to first and p.second to second.
Returns: *this.
template<class U1, class U2> constexpr const pair& operator=(const pair<U1, U2>& p) const;
Constraints:
  • is_assignable_v<const T1&, const U1&> is true, and
  • is_assignable_v<const T2&, const U2&> is true.
Effects: Assigns p.first to first and p.second to second.
Returns: *this.
constexpr pair& operator=(pair&& p) noexcept(see below);
Constraints:
  • is_move_assignable_v<T1> is true and
  • is_move_assignable_v<T2> is true.
Effects: Assigns std​::​forward<T1>(p.first) to first and std​::​forward<T2>(p.second) to second.
Returns: *this.
Remarks: The exception specification is equivalent to: is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
constexpr const pair& operator=(pair&& p) const;
Constraints:
  • is_assignable_v<const T1&, T1> is true and
  • is_assignable_v<const T2&, T2> is true.
Effects: Assigns std​::​forward<T1>(p.first) to first and std​::​forward<T2>(p.second) to second.
Returns: *this.
template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
Constraints:
  • is_assignable_v<T1&, U1> is true and
  • is_assignable_v<T2&, U2> is true.
Effects: Assigns std​::​forward<U1>(p.first) first and std​::​forward<U2>(p.second) to second.
Returns: *this.
template<pair-like P> constexpr pair& operator=(P&& p);
Constraints:
Effects: Assigns get<0>(std​::​forward<P>(p)) to first and get<1>(std​::​forward<P>(p)) to second.
Returns: *this.
template<pair-like P> constexpr const pair& operator=(P&& p) const;
Constraints:
  • different-from<P, pair> ([range.utility.helpers]) is true,
  • remove_cvref_t<P> is not a specialization of ranges​::​subrange,
  • is_assignable_v<const T1&, decltype(get<0>(std​::​forward<P>(p)))> is true, and
  • is_assignable_v<const T2&, decltype(get<1>(std​::​forward<P>(p)))> is true.
Effects: Assigns get<0>(std​::​forward<P>(p)) to first and get<1>(std​::​forward<P>(p)) to second.
Returns: *this.
template<class U1, class U2> constexpr const pair& operator=(pair<U1, U2>&& p) const;
Constraints:
  • is_assignable_v<const T1&, U1> is true, and
  • is_assignable_v<const T2&, U2> is true.
Effects: Assigns std​::​forward<U1>(p.first) to first and std​::​forward<U2>(u.second) to second.
Returns: *this.
constexpr void swap(pair& p) noexcept(see below); constexpr void swap(const pair& p) const noexcept(see below);
Mandates:
  • For the first overload, is_swappable_v<T1> is true and is_swappable_v<T2> is true.
  • For the second overload, is_swappable_v<const T1> is true and is_swappable_v<const T2> is true.
Preconditions: first is swappable with ([swappable.requirements]) p.first and second is swappable with p.second.
Effects: Swaps first with p.first and second with p.second.
Remarks: The exception specification is equivalent to:
  • is_nothrow_swappable_v<T1> && is_nothrow_swappable_v<T2> for the first overload, and
  • is_nothrow_swappable_v<const T1> && is_nothrow_swappable_v<const T2> for the second overload.

22.3.3 Specialized algorithms [pairs.spec]

template<class T1, class T2, class U1, class U2> constexpr bool operator==(const pair<T1, T2>& x, const pair<U1, U2>& y);
Constraints: x.first == y.first and x.second == y.second are valid expressions and each of decltype(x.first == y.first) and decltype(x.second == y.second) models boolean-
testable
.
Returns: x.first == y.first && x.second == y.second.
template<class T1, class T2, class U1, class U2> constexpr common_comparison_category_t<synth-three-way-result<T1, U1>, synth-three-way-result<T2, U2>> operator<=>(const pair<T1, T2>& x, const pair<U1, U2>& y);
Effects: Equivalent to: if (auto c = synth-three-way(x.first, y.first); c != 0) return c; return synth-three-way(x.second, y.second);
template<class T1, class T2> constexpr void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); template<class T1, class T2> constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
Constraints:
  • For the first overload, is_swappable_v<T1> is true and is_swappable_v<T2> is true.
  • For the second overload, is_swappable_v<const T1> is true and is_swappable_v<const T2> is true.
Effects: Equivalent to x.swap(y).
template<class T1, class T2> constexpr pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>> make_pair(T1&& x, T2&& y);
Returns: pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>>(std::forward<T1>(x), std::forward<T2>(y))
[Example 1: 
In place of: return pair<int, double>(5, 3.1415926); // explicit types a C++ program may contain: return make_pair(5, 3.1415926); // types are deduced
— end example]

22.3.4 Tuple-like access to pair [pair.astuple]

template<class T1, class T2> struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
template<size_t I, class T1, class T2> struct tuple_element<I, pair<T1, T2>> { using type = see below ; };
Mandates: .
Type: The type T1 if I is 0, otherwise the type T2.
template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
Mandates: .
Returns:
  • If I is 0, returns a reference to p.first.
  • If I is 1, returns a reference to p.second.
template<class T1, class T2> constexpr T1& get(pair<T1, T2>& p) noexcept; template<class T1, class T2> constexpr const T1& get(const pair<T1, T2>& p) noexcept; template<class T1, class T2> constexpr T1&& get(pair<T1, T2>&& p) noexcept; template<class T1, class T2> constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
Mandates: T1 and T2 are distinct types.
Returns: A reference to p.first.
template<class T2, class T1> constexpr T2& get(pair<T1, T2>& p) noexcept; template<class T2, class T1> constexpr const T2& get(const pair<T1, T2>& p) noexcept; template<class T2, class T1> constexpr T2&& get(pair<T1, T2>&& p) noexcept; template<class T2, class T1> constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
Mandates: T1 and T2 are distinct types.
Returns: A reference to p.second.

22.3.5 Piecewise construction [pair.piecewise]

struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{};
The struct piecewise_construct_t is an empty class type used as a unique type to disambiguate constructor and function overloading.
Specifically, pair has a constructor with piecewise_construct_t as the first argument, immediately followed by two tuple arguments used for piecewise construction of the elements of the pair object.

22.4 Tuples [tuple]

22.4.1 General [tuple.general]

Subclause [tuple] describes the tuple library that provides a tuple type as the class template tuple that can be instantiated with any number of arguments.
Each template argument specifies the type of an element in the tuple.
Consequently, tuples are heterogeneous, fixed-size collections of values.
An instantiation of tuple with two arguments is similar to an instantiation of pair with the same two arguments.
In addition to being available via inclusion of the <tuple> header, ignore ([tuple.syn]) is available when <utility> ([utility]) is included.

22.4.2 Header <tuple> synopsis [tuple.syn]

// all freestanding #include <compare> // see [compare.syn] namespace std { // [tuple.tuple], class template tuple template<class... Types> class tuple; // [tuple.like], concept tuple-like template<class T> concept tuple-like = see below; // exposition only template<class T> concept pair-like = // exposition only tuple-like<T> && tuple_size_v<remove_cvref_t<T>> == 2; // [tuple.common.ref], common_reference related specializations template<tuple-like TTuple, tuple-like UTuple, template<class> class TQual, template<class> class UQual> struct basic_common_reference<TTuple, UTuple, TQual, UQual>; template<tuple-like TTuple, tuple-like UTuple> struct common_type<TTuple, UTuple>; // ignore struct ignore-type { // exposition only constexpr const ignore-type operator=(const auto &) const noexcept { return *this; } }; inline constexpr ignore-type ignore; // [tuple.creation], tuple creation functions template<class... TTypes> constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&...); template<class... TTypes> constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept; template<class... TTypes> constexpr tuple<TTypes&...> tie(TTypes&...) noexcept; template<tuple-like... Tuples> constexpr tuple<CTypes...> tuple_cat(Tuples&&...); // [tuple.apply], calling a function with a tuple of arguments template<class F, tuple-like Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(see below); template<class T, tuple-like Tuple> constexpr T make_from_tuple(Tuple&& t); // [tuple.helper], tuple helper classes template<class T> struct tuple_size; // not defined template<class T> struct tuple_size<const T>; template<class... Types> struct tuple_size<tuple<Types...>>; template<size_t I, class T> struct tuple_element; // not defined template<size_t I, class T> struct tuple_element<I, const T>; template<size_t I, class... Types> struct tuple_element<I, tuple<Types...>>; template<size_t I, class T> using tuple_element_t = typename tuple_element<I, T>::type; // [tuple.elem], element access template<size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept; template<size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept; template<size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&) noexcept; template<size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept; template<class T, class... Types> constexpr T& get(tuple<Types...>& t) noexcept; template<class T, class... Types> constexpr T&& get(tuple<Types...>&& t) noexcept; template<class T, class... Types> constexpr const T& get(const tuple<Types...>& t) noexcept; template<class T, class... Types> constexpr const T&& get(const tuple<Types...>&& t) noexcept; // [tuple.rel], relational operators template<class... TTypes, class... UTypes> constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, tuple-like UTuple> constexpr bool operator==(const tuple<TTypes...>&, const UTuple&); template<class... TTypes, class... UTypes> constexpr common_comparison_category_t<synth-three-way-result<TTypes, UTypes>...> operator<=>(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, tuple-like UTuple> constexpr see below operator<=>(const tuple<TTypes...>&, const UTuple&); // [tuple.traits], allocator-related traits template<class... Types, class Alloc> struct uses_allocator<tuple<Types...>, Alloc>; // [tuple.special], specialized algorithms template<class... Types> constexpr void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below); template<class... Types> constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see below); // [tuple.helper], tuple helper classes template<class T> constexpr size_t tuple_size_v = tuple_size<T>::value; }

22.4.3 Concept tuple-like [tuple.like]

template<class T> concept tuple-like = see below; // exposition only
A type T models and satisfies the exposition-only concept tuple-like if remove_cvref_t<T> is a specialization of array, complex, pair, tuple, or ranges​::​subrange.

22.4.4 Class template tuple [tuple.tuple]

22.4.4.1 General [tuple.tuple.general]

namespace std { template<class... Types> class tuple { public: // [tuple.cnstr], tuple construction constexpr explicit(see below) tuple(); constexpr explicit(see below) tuple(const Types&...); // only if sizeof...(Types) >= 1 template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&...); // only if sizeof...(Types) >= 1 tuple(const tuple&) = default; tuple(tuple&&) = default; template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&); template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&); template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&&); template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&&); template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>&&); // only if sizeof...(Types) == 2 template<tuple-like UTuple> constexpr explicit(see below) tuple(UTuple&&); // allocator-extended constructors template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a); template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const Types&...); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&); template<class Alloc, tuple-like UTuple> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTuple&&); // [tuple.assign], tuple assignment constexpr tuple& operator=(const tuple&); constexpr const tuple& operator=(const tuple&) const; constexpr tuple& operator=(tuple&&) noexcept(see below); constexpr const tuple& operator=(tuple&&) const; template<class... UTypes> constexpr tuple& operator=(const tuple<UTypes...>&); template<class... UTypes> constexpr const tuple& operator=(const tuple<UTypes...>&) const; template<class... UTypes> constexpr tuple& operator=(tuple<UTypes...>&&); template<class... UTypes> constexpr const tuple& operator=(tuple<UTypes...>&&) const; template<class U1, class U2> constexpr tuple& operator=(const pair<U1, U2>&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr const tuple& operator=(const pair<U1, U2>&) const; // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr tuple& operator=(pair<U1, U2>&&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr const tuple& operator=(pair<U1, U2>&&) const; // only if sizeof...(Types) == 2 template<tuple-like UTuple> constexpr tuple& operator=(UTuple&&); template<tuple-like UTuple> constexpr const tuple& operator=(UTuple&&) const; // [tuple.swap], tuple swap constexpr void swap(tuple&) noexcept(see below); constexpr void swap(const tuple&) const noexcept(see below); }; template<class... UTypes> tuple(UTypes...) -> tuple<UTypes...>; template<class T1, class T2> tuple(pair<T1, T2>) -> tuple<T1, T2>; template<class Alloc, class... UTypes> tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>; template<class Alloc, class T1, class T2> tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; template<class Alloc, class... UTypes> tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>; }
If a program declares an explicit or partial specialization of tuple, the program is ill-formed, no diagnostic required.

22.4.4.2 Construction [tuple.cnstr]

In the descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, be the type in Types, and be the type in a template parameter pack named UTypes, where indexing is zero-based.
For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception.
The defaulted move and copy constructor, respectively, of tuple is a constexpr function if and only if all required element-wise initializations for move and copy, respectively, would be constexpr-suitable ([dcl.constexpr]).
The defaulted move and copy constructor of tuple<> are constexpr functions.
If is_trivially_destructible_v<> is true for all , then the destructor of tuple is trivial.
The default constructor of tuple<> is trivial.
constexpr explicit(see below) tuple();
Constraints: is_default_constructible_v<> is true for all i.
Effects: Value-initializes each element.
Remarks: The expression inside explicit evaluates to true if and only if is not copy-list-initializable from an empty list for at least one i.
[Note 1: 
This behavior can be implemented with a trait that checks whether a const & can be initialized with {}.
— end note]
constexpr explicit(see below) tuple(const Types&...);
Constraints: sizeof...(Types)  ≥ 1 and is_copy_constructible_v<> is true for all i.
Effects: Initializes each element with the value of the corresponding parameter.
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<const Types&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&... u);
Let disambiguating-constraint be:
  • negation<is_same<remove_cvref_t<>, tuple>> if sizeof...(Types) is 1;
  • otherwise, bool_constant<!is_same_v<remove_cvref_t<>, allocator_arg_t> || is_-
    same_v<remove_cvref_t<>, allocator_arg_t>>
    if sizeof...(Types) is 2 or 3;
  • otherwise, true_type.
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes),
  • sizeof...(Types)  ≥ 1, and
  • conjunction_v<disambiguating-constraint, is_constructible<Types, UTypes>...> is
    true.
Effects: Initializes the elements in the tuple with the corresponding value in std​::​forward<UTypes>(u).
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<UTypes, Types>...>
This constructor is defined as deleted if (reference_constructs_from_temporary_v<Types, UTypes&&> || ...) is true.
tuple(const tuple& u) = default;
Mandates: is_copy_constructible_v<> is true for all i.
Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
Constraints: is_move_constructible_v<> is true for all i.
Effects: For all i, initializes the element of *this with std​::​forward<>(get<i>(u)).
template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>& u); template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u); template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u); template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&& u);
Let I be the pack 0, 1, ..., (sizeof...(Types) - 1).

Let FWD(u) be static_cast<decltype(u)>(u).
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes), and
  • (is_constructible_v<Types, decltype(get<I>(FWD(u)))> && ...) is true, and
  • either sizeof...(Types) is not 1, or (when Types... expands to T and UTypes... expands to U) is_convertible_v<decltype(u), T>, is_constructible_v<T, decltype(u)>, and is_same_v<T, U> are all false.
Effects: For all i, initializes the element of *this with get<i>(FWD(u)).
Remarks: The expression inside explicit is equivalent to: !(is_convertible_v<decltype(get<I>(FWD(u))), Types> && ...)
The constructor is defined as deleted if (reference_constructs_from_temporary_v<Types, decltype(get<I>(FWD(u)))> || ...) is true.
template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>& u); template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u); template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&& u); template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>&& u);
Let FWD(u) be static_cast<decltype(u)>(u).
Constraints:
  • sizeof...(Types) is 2,
  • is_constructible_v<, decltype(get<0>(FWD(u)))> is true, and
  • is_constructible_v<, decltype(get<1>(FWD(u)))> is true.
Effects: Initializes the first element with get<0>(FWD(u)) and the second element with get<1>(FWD(​u)).
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<decltype(get<0>(FWD(u))), > || !is_convertible_v<decltype(get<1>(FWD(u))), >
The constructor is defined as deleted if reference_constructs_from_temporary_v<, decltype(get<0>(FWD(u)))> || reference_constructs_from_temporary_v<, decltype(get<1>(FWD(u)))> is true.
template<tuple-like UTuple> constexpr explicit(see below) tuple(UTuple&& u);
Let I be the pack 0, 1, …, (sizeof...(Types) - 1).
Constraints:
  • different-from<UTuple, tuple> ([range.utility.helpers]) is true,
  • remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
  • sizeof...(Types) equals tuple_size_v<remove_cvref_t<UTuple>>,
  • (is_constructible_v<Types, decltype(get<I>(std​::​forward<UTuple>(u)))> && ...) is true, and
  • either sizeof...(Types) is not 1, or (when Types... expands to T) is_convertible_v<UTuple, T> and is_constructible_v<T, UTuple> are both false.
Effects: For all i, initializes the element of *this with get<i>(std​::​forward<UTuple>(u)).
Remarks: The expression inside explicit is equivalent to: !(is_convertible_v<decltype(get<I>(std::forward<UTuple>(u))), Types> && ...)
The constructor is defined as deleted if (reference_constructs_from_temporary_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> || ...) is true.
template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a); template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const Types&...); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&); template<class Alloc, tuple-like UTuple> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTuple&&);
Preconditions: Alloc meets the Cpp17Allocator requirements ([allocator.requirements.general]).
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction.

22.4.4.3 Assignment [tuple.assign]

For each tuple assignment operator, an exception is thrown only if the assignment of one of the types in Types throws an exception.
In the function descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, be the type in Types, and be the type in a template parameter pack named UTypes, where indexing is zero-based.
constexpr tuple& operator=(const tuple& u);
Effects: Assigns each element of u to the corresponding element of *this.
Returns: *this.
Remarks: This operator is defined as deleted unless is_copy_assignable_v<> is true for all i.
constexpr const tuple& operator=(const tuple& u) const;
Constraints: (is_copy_assignable_v<const Types> && ...) is true.
Effects: Assigns each element of u to the corresponding element of *this.
Returns: *this.
constexpr tuple& operator=(tuple&& u) noexcept(see below);
Constraints: is_move_assignable_v<> is true for all i.
Effects: For all i, assigns std​::​forward<>(get<i>(u)) to get<i>(*this).
Returns: *this.
Remarks: The exception specification is equivalent to the logical and of the following expressions: is_nothrow_move_assignable_v<> where is the type in Types.
constexpr const tuple& operator=(tuple&& u) const;
Constraints: (is_assignable_v<const Types&, Types> && ...) is true.
Effects: For all i, assigns std​::​forward<T>(get<i>(u)) to get<i>(*this).
Returns: *this.
template<class... UTypes> constexpr tuple& operator=(const tuple<UTypes...>& u);
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes) and
  • is_assignable_v<&, const &> is true for all i.
Effects: Assigns each element of u to the corresponding element of *this.
Returns: *this.
template<class... UTypes> constexpr const tuple& operator=(const tuple<UTypes...>& u) const;
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes) and
  • (is_assignable_v<const Types&, const UTypes&> && ...) is true.
Effects: Assigns each element of u to the corresponding element of *this.
Returns: *this.
template<class... UTypes> constexpr tuple& operator=(tuple<UTypes...>&& u);
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes) and
  • is_assignable_v<&, > is true for all i.
Effects: For all i, assigns std​::​forward<>(get<i>(u)) to get<i>(*this).
Returns: *this.
template<class... UTypes> constexpr const tuple& operator=(tuple<UTypes...>&& u) const;
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes) and
  • (is_assignable_v<const Types&, UTypes> && ...) is true.
Effects: For all i, assigns std​::​forward<U>(get<i>(u)) to get<i>(*this).
Returns: *this.
template<class U1, class U2> constexpr tuple& operator=(const pair<U1, U2>& u);
Constraints:
  • sizeof...(Types) is 2 and
  • is_assignable_v<&, const U1&> is true, and
  • is_assignable_v<&, const U2&> is true.
Effects: Assigns u.first to the first element of *this and u.second to the second element of *this.
Returns: *this.
template<class U1, class U2> constexpr const tuple& operator=(const pair<U1, U2>& u) const;
Constraints:
  • sizeof...(Types) is 2,
  • is_assignable_v<const &, const U1&> is true, and
  • is_assignable_v<const &, const U2&> is true.
Effects: Assigns u.first to the first element and u.second to the second element.
Returns: *this.
template<class U1, class U2> constexpr tuple& operator=(pair<U1, U2>&& u);
Constraints:
  • sizeof...(Types) is 2 and
  • is_assignable_v<&, U1> is true, and
  • is_assignable_v<&, U2> is true.
Effects: Assigns std​::​forward<U1>(u.first) to the first element of *this and
std​::​forward<U2>(u.second) to the second element of *this.
Returns: *this.
template<class U1, class U2> constexpr const tuple& operator=(pair<U1, U2>&& u) const;
Constraints:
  • sizeof...(Types) is 2,
  • is_assignable_v<const &, U1> is true, and
  • is_assignable_v<const &, U2> is true.
Effects: Assigns std​::​forward<U1>(u.first) to the first element and
std​::​forward<U2>(u.second) to the second element.
Returns: *this.
template<tuple-like UTuple> constexpr tuple& operator=(UTuple&& u);
Constraints:
  • different-from<UTuple, tuple> ([range.utility.helpers]) is true,
  • remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
  • sizeof...(Types) equals tuple_size_v<remove_cvref_t<UTuple>>, and,
  • is_assignable_v<&, decltype(get<i>(std​::​forward<UTuple>(u)))> is true for all i.
Effects: For all i, assigns get<i>(std​::​forward<UTuple>(u)) to get<i>(*this).
Returns: *this.
template<tuple-like UTuple> constexpr const tuple& operator=(UTuple&& u) const;
Constraints:
  • different-from<UTuple, tuple> ([range.utility.helpers]) is true,
  • remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
  • sizeof...(Types) equals tuple_size_v<remove_cvref_t<UTuple>>, and,
  • is_assignable_v<const &, decltype(get<i>(std​::​forward<UTuple>(u)))> is true for all i.
Effects: For all i, assigns get<i>(std​::​forward<UTuple>(u)) to get<i>(*this).
Returns: *this.

22.4.4.4 swap [tuple.swap]

constexpr void swap(tuple& rhs) noexcept(see below); constexpr void swap(const tuple& rhs) const noexcept(see below);
Let i be in the range [0, sizeof...(Types)) in order.
Mandates:
  • For the first overload, (is_swappable_v<Types> && ...) is true.
  • For the second overload, (is_swappable_v<const Types> && ...) is true.
Preconditions: For all i, get<i>(*this) is swappable with ([swappable.requirements]) get<i>(rhs).
Effects: For each i, calls swap for get<i>(*this) and get<i>(rhs).
Throws: Nothing unless one of the element-wise swap calls throws an exception.
Remarks: The exception specification is equivalent to
  • (is_nothrow_swappable_v<Types> && ...) for the first overload and
  • (is_nothrow_swappable_v<const Types> && ...) for the second overload.

22.4.5 Tuple creation functions [tuple.creation]

template<class... TTypes> constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&... t);
Returns: tuple<unwrap_ref_decay_t<TTypes>...>(std​::​forward<TTypes>(t)...).
[Example 1: 
int i; float j; make_tuple(1, ref(i), cref(j)); creates a tuple of type tuple<int, int&, const float&>.
— end example]
template<class... TTypes> constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&... t) noexcept;
Effects: Constructs a tuple of references to the arguments in t suitable for forwarding as arguments to a function.
Because the result may contain references to temporary objects, a program shall ensure that the return value of this function does not outlive any of its arguments (e.g., the program should typically not store the result in a named variable).
Returns: tuple<TTypes&&...>(std​::​forward<TTypes>(t)...).
template<class... TTypes> constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
Returns: tuple<TTypes&...>(t...).
[Example 2: 
tie functions allow one to create tuples that unpack tuples into variables.
ignore can be used for elements that are not needed: int i; std::string s; tie(i, ignore, s) = make_tuple(42, 3.14, "C++"); // i == 42, s == "C++"
— end example]
template<tuple-like... Tuples> constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
Let n be sizeof...(Tuples).
For every integer :
  • Let be the type in Tuples.
  • Let be remove_cvref_t<>.
  • Let be the element in the function parameter pack tpls.
  • Let be tuple_size_v<>.
  • Let be tuple_element_t<k, >.
  • Let be get<k>(std​::​forward<>()).
  • Let be a pack of the types .
  • Let be a pack of the expressions .
The types in CTypes are equal to the ordered sequence of the expanded packs of types ..., ..., …, ....
Let celems be the ordered sequence of the expanded packs of expressions ..., …, ....
Mandates: (is_constructible_v<CTypes, decltype(celems)> && ...) is true.
Returns: tuple<CTypes...>(celems...).

22.4.6 Calling a function with a tuple of arguments [tuple.apply]

template<class F, tuple-like Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(see below);
Effects: Given the exposition-only function template: namespace std { template<class F, tuple-like Tuple, size_t... I> constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, index_sequence<I...>) { // exposition only return INVOKE(std::forward<F>(f), get<I>(std::forward<Tuple>(t))...); // see [func.require] } }
Equivalent to: return apply-impl(std::forward<F>(f), std::forward<Tuple>(t), make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
Remarks: Let I be the pack 0, 1, ..., (tuple_size_v<remove_reference_t<Tuple>> - 1).
The exception specification is equivalent to: noexcept(invoke(std::forward<F>(f), get<I>(std::forward<Tuple>(t))...))
template<class T, tuple-like Tuple> constexpr T make_from_tuple(Tuple&& t);
Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.
Effects: Given the exposition-only function template: namespace std { template<class T, tuple-like Tuple, size_t... I> requires is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...> constexpr T make-from-tuple-impl(Tuple&& t, index_sequence<I...>) { // exposition only return T(get<I>(std::forward<Tuple>(t))...); } }
Equivalent to: return make-from-tuple-impl<T>( std::forward<Tuple>(t), make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
[Note 1: 
The type of T must be supplied as an explicit template parameter, as it cannot be deduced from the argument list.
— end note]

22.4.7 Tuple helper classes [tuple.helper]

template<class T> struct tuple_size;
Except where specified otherwise, all specializations of tuple_size meet the Cpp17UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_constant<size_t, N> for some N.
template<class... Types> struct tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
template<size_t I, class... Types> struct tuple_element<I, tuple<Types...>> { using type = TI; };
Mandates: I < sizeof...(Types).
Type: TI is the type of the element of Types, where indexing is zero-based.
template<class T> struct tuple_size<const T>;
Let TS denote tuple_size<T> of the cv-unqualified type T.
If the expression TS​::​value is well-formed when treated as an unevaluated operand, then each specialization of the template meets the Cpp17UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_constant<size_t, TS::value>
Otherwise, it has no member value.
Access checking is performed as if in a context unrelated to TS and T.
Only the validity of the immediate context of the expression is considered.
[Note 1: 
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
— end note]
In addition to being available via inclusion of the <tuple> header, the template is available when any of the headers <array>, <ranges>, or <utility> are included.
template<size_t I, class T> struct tuple_element<I, const T>;
Let TE denote tuple_element_t<I, T> of the cv-unqualified type T.
Then each specialization of the template meets the Cpp17TransformationTrait requirements ([meta.rqmts]) with a member typedef type that names the type add_const_t<TE>.
In addition to being available via inclusion of the <tuple> header, the template is available when any of the headers <array>, <ranges>, or <utility> are included.

22.4.8 Element access [tuple.elem]

template<size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>& t) noexcept; template<size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&& t) noexcept; // #1 template<size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>& t) noexcept; // #2 template<size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
Mandates: I < sizeof...(Types).
Returns: A reference to the element of t, where indexing is zero-based.
[Note 1: 
For the overload marked #1, if a type T in Types is some reference type X&, the return type is X&, not X&&.
However, if the element type is a non-reference type T, the return type is T&&.
— end note]
[Note 2: 
Constness is shallow.
For the overload marked #2, if a type T in Types is some reference type X&, the return type is X&, not const X&.
However, if the element type is a non-reference type T, the return type is const T&.
This is consistent with how constness is defined to work for non-static data members of reference type.
— end note]
template<class T, class... Types> constexpr T& get(tuple<Types...>& t) noexcept; template<class T, class... Types> constexpr T&& get(tuple<Types...>&& t) noexcept; template<class T, class... Types> constexpr const T& get(const tuple<Types...>& t) noexcept; template<class T, class... Types> constexpr const T&& get(const tuple<Types...>&& t) noexcept;
Mandates: The type T occurs exactly once in Types.
Returns: A reference to the element of t corresponding to the type T in Types.
[Example 1: const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6); const int& i1 = get<int>(t); // OK, i1 has value 1 const int& i2 = get<const int>(t); // OK, i2 has value 2 const double& d = get<double>(t); // error: type double is not unique within t — end example]
[Note 3: 
The reason get is a non-member function is that if this functionality had been provided as a member function, code where the type depended on a template parameter would have required using the template keyword.
— end note]

22.4.9 Relational operators [tuple.rel]

template<class... TTypes, class... UTypes> constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u); template<class... TTypes, tuple-like UTuple> constexpr bool operator==(const tuple<TTypes...>& t, const UTuple& u);
For the first overload let UTuple be tuple<UTypes...>.
Constraints: For all i, where 0  ≤ i < sizeof...(TTypes), get<i>(t) == get<i>(u) is a valid expression and decltype(get<i>(t) == get<i>(u)) models boolean-testable.
sizeof...(TTypes) equals tuple_size_v<UTuple>.
Returns: true if get<i>(t) == get<i>(u) for all i, otherwise false.
[Note 1: 
If sizeof...(TTypes) equals zero, returns true.
— end note]
Remarks:
  • The elementary comparisons are performed in order from the zeroth index upwards.
    No comparisons or element accesses are performed after the first equality comparison that evaluates to false.
  • The second overload is to be found via argument-dependent lookup ([basic.lookup.argdep]) only.
template<class... TTypes, class... UTypes> constexpr common_comparison_category_t<synth-three-way-result<TTypes, UTypes>...> operator<=>(const tuple<TTypes...>& t, const tuple<UTypes...>& u); template<class... TTypes, tuple-like UTuple> constexpr common_comparison_category_t<synth-three-way-result<TTypes, Elems>...> operator<=>(const tuple<TTypes...>& t, const UTuple& u);
For the second overload, Elems denotes the pack of types tuple_element_t<0, UTuple>, tuple_element_t<1, UTuple>, …, tuple_element_t<tuple_size_v<UTuple> - 1, UTuple>.
Effects: Performs a lexicographical comparison between t and u.
If sizeof...(TTypes) equals zero, returns strong_ordering​::​equal.
Otherwise, equivalent to: if (auto c = synth-three-way(get<0>(t), get<0>(u)); c != 0) return c; return <=> ; where for some r is a tuple containing all but the first element of r.
Remarks: The second overload is to be found via argument-dependent lookup ([basic.lookup.argdep]) only.
[Note 2: 
The above definition does not require t (or u) to be constructed.
It might not even be possible, as t and u are not required to be copy constructible.
Also, all comparison operator functions are short circuited; they do not perform element accesses beyond what is needed to determine the result of the comparison.
— end note]

22.4.10 common_reference related specializations [tuple.common.ref]

In the descriptions that follow:
  • Let TTypes be a pack formed by the sequence of tuple_element_t<i, TTuple> for every integer .
  • Let UTypes be a pack formed by the sequence of tuple_element_t<i, UTuple> for every integer .
template<tuple-like TTuple, tuple-like UTuple, template<class> class TQual, template<class> class UQual> struct basic_common_reference<TTuple, UTuple, TQual, UQual> { using type = see below; };
Constraints:
  • TTuple is a specialization of tuple or UTuple is a specialization of tuple.
  • is_same_v<TTuple, decay_t<TTuple>> is true.
  • is_same_v<UTuple, decay_t<UTuple>> is true.
  • tuple_size_v<TTuple> equals tuple_size_v<UTuple>.
  • tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...> denotes a type.
The member typedef-name type denotes the type tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>.
template<tuple-like TTuple, tuple-like UTuple> struct common_type<TTuple, UTuple> { using type = see below; };
Constraints:
  • TTuple is a specialization of tuple or UTuple is a specialization of tuple.
  • is_same_v<TTuple, decay_t<TTuple>> is true.
  • is_same_v<UTuple, decay_t<UTuple>> is true.
  • tuple_size_v<TTuple> equals tuple_size_v<UTuple>.
  • tuple<common_type_t<TTypes, UTypes>...> denotes a type.
The member typedef-name type denotes the type tuple<common_type_t<TTypes, UTypes>...>.

22.4.11 Tuple traits [tuple.traits]

template<class... Types, class Alloc> struct uses_allocator<tuple<Types...>, Alloc> : true_type { };
Preconditions: Alloc meets the Cpp17Allocator requirements ([allocator.requirements.general]).
[Note 1: 
Specialization of this trait informs other library components that tuple can be constructed with an allocator, even though it does not have a nested allocator_type.
— end note]

22.4.12 Tuple specialized algorithms [tuple.special]

template<class... Types> constexpr void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below); template<class... Types> constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see below);
Constraints:
  • For the first overload, (is_swappable_v<Types> && ...) is true.
  • For the second overload, (is_swappable_v<const Types> && ...) is true.
Effects: As if by x.swap(y).
Remarks: The exception specification is equivalent to: noexcept(x.swap(y))

22.5 Optional objects [optional]

22.5.1 General [optional.general]

Subclause [optional] describes class template optional that represents optional objects.
An optional object is an object that contains the storage for another object and manages the lifetime of this contained object, if any.
The contained object may be initialized after the optional object has been initialized, and may be destroyed before the optional object has been destroyed.
The initialization state of the contained object is tracked by the optional object.

22.5.2 Header <optional> synopsis [optional.syn]

// mostly freestanding #include <compare> // see [compare.syn] namespace std { // [optional.optional], class template optional template<class T> class optional; // partially freestanding template<class T> constexpr bool ranges::enable_view<optional<T>> = true; template<class T> constexpr auto format_kind<optional<T>> = range_format::disabled; template<class T> concept is-derived-from-optional = requires(const T& t) { // exposition only []<class U>(const optional<U>&){ }(t); }; // [optional.nullopt], no-value state indicator struct nullopt_t{see below}; inline constexpr nullopt_t nullopt(unspecified); // [optional.bad.access], class bad_optional_access class bad_optional_access; // [optional.relops], relational operators template<class T, class U> constexpr bool operator==(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator!=(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator<(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator>(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator<=(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator>=(const optional<T>&, const optional<U>&); template<class T, three_way_comparable_with<T> U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>&, const optional<U>&); // [optional.nullops], comparison with nullopt template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; template<class T> constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // [optional.comp.with.t], comparison with T template<class T, class U> constexpr bool operator==(const optional<T>&, const U&); template<class T, class U> constexpr bool operator==(const T&, const optional<U>&); template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&); template<class T, class U> constexpr bool operator<(const optional<T>&, const U&); template<class T, class U> constexpr bool operator<(const T&, const optional<U>&); template<class T, class U> constexpr bool operator>(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>(const T&, const optional<U>&); template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&); template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); template<class T, class U> requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>&, const U&); // [optional.specalg], specialized algorithms template<class T> constexpr void swap(optional<T>&, optional<T>&) noexcept(see below); template<class T> constexpr optional<decay_t<T>> make_optional(T&&); template<class T, class... Args> constexpr optional<T> make_optional(Args&&... args); template<class T, class U, class... Args> constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); // [optional.hash], hash support template<class T> struct hash; template<class T> struct hash<optional<T>>; }

22.5.3 Class template optional [optional.optional]

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: T* val; // exposition only }; template<class T> optional(T) -> optional<T>; }
Any instance of optional<T> at any given time either contains a value or does not contain a value.
When an instance of optional<T> contains a value, it means that an object of type T, referred to as the optional object's contained value, is nested within ([intro.object]) the optional object.
When an object of type optional<T> is contextually converted to bool, the conversion returns true if the object contains a value; otherwise the conversion returns false.
When an optional<T> object contains a value, member val points to the contained value.
T shall be a type other than cv in_place_t or cv nullopt_t that meets the Cpp17Destructible requirements (Table 35).

22.5.3.2 Constructors [optional.ctor]

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;
Postconditions: *this does not contain a value.
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 the contained value with *rhs.
Postconditions: rhs.has_value() == this->has_value().
Throws: Any exception thrown by the selected constructor of T.
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);
Constraints: is_move_constructible_v<T> is true.
Effects: If rhs contains a value, direct-non-list-initializes the contained value with std​::​move(*rhs).
rhs.has_value() is unchanged.
Postconditions: rhs.has_value() == this->has_value().
Throws: Any exception thrown by the selected constructor of T.
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);
Constraints: is_constructible_v<T, Args...> is true.
Effects: Direct-non-list-initializes the contained value with std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
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);
Constraints: is_constructible_v<T, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes the contained value with il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
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 the contained value with std​::​forward<U>(v).
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
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 the contained value with *rhs.
Postconditions: rhs.has_value() == this->has_value().
Throws: Any exception thrown by the selected constructor of T.
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 the contained value with std​::​move(*rhs).
rhs.has_value() is unchanged.
Postconditions: rhs.has_value() == this->has_value().
Throws: Any exception thrown by the selected constructor of T.
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<U, T>

22.5.3.3 Destructor [optional.dtor]

constexpr ~optional();
Effects: If is_trivially_destructible_v<T> != true and *this contains a value, calls val->T::~T()
Remarks: If is_trivially_destructible_v<T> is true, then this destructor is trivial.

22.5.3.4 Assignment [optional.assign]

constexpr optional<T>& operator=(nullopt_t) 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.
Returns: *this.
constexpr optional<T>& operator=(const optional& rhs);
Effects: See Table 62.
Table 62: optional​::​operator=(const optional&) effects [tab:optional.assign.copy]
*this contains a value
*this does not contain a value
rhs contains a value
assigns *rhs to the contained value
direct-non-list-initializes the contained value with *rhs
rhs does not contain a value
destroys the contained value by calling val->T​::​~T()
no effect
Postconditions: rhs.has_value() == this->has_value().
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 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.
Effects: See Table 63.
The result of the expression rhs.has_value() remains unchanged.
Table 63: optional​::​operator=(optional&&) effects [tab:optional.assign.move]
*this contains a value
*this does not contain a value
rhs contains a value
assigns std​::​move(*rhs) to the contained value
direct-non-list-initializes the contained value with std​::​move(*rhs)
rhs does not contain a value
destroys the contained value by calling val->T​::​~T()
no effect
Postconditions: rhs.has_value() == this->has_value().
Returns: *this.
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 state of *val and *rhs.val is 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);
Constraints:
  • is_same_v<remove_cvref_t<U>, optional> is false,
  • conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false,
  • is_constructible_v<T, U> is true, and
  • is_assignable_v<T&, U> is true.
Effects: If *this contains a value, assigns std​::​forward<U>(v) to the contained value; otherwise direct-non-list-initializes the contained value with std​::​forward<U>(v).
Postconditions: *this contains a value.
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 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 state of *val and v is determined by the exception safety guarantee of T's assignment.
template<class U> constexpr optional<T>& operator=(const optional<U>& rhs);
Constraints:
  • is_constructible_v<T, const U&> is true,
  • is_assignable_v<T&, const U&> is true,
  • converts-from-any-cvref<T, optional<U>> is false,
  • is_assignable_v<T&, optional<U>&> is false,
  • is_assignable_v<T&, optional<U>&&> is false,
  • is_assignable_v<T&, const optional<U>&> is false, and
  • is_assignable_v<T&, const optional<U>&&> is false.
Effects: See Table 64.
Table 64: optional​::​operator=(const optional<U>&) effects [tab:optional.assign.copy.templ]
*this contains a value
*this does not contain a value
rhs contains a value
assigns *rhs to the contained value
direct-non-list-initializes the contained value with *rhs
rhs does not contain a value
destroys the contained value by calling val->T​::​~T()
no effect
Postconditions: rhs.has_value() == this->has_value().
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 state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment.
template<class U> constexpr optional<T>& operator=(optional<U>&& rhs);
Constraints:
  • is_constructible_v<T, U> is true,
  • is_assignable_v<T&, U> is true,
  • converts-from-any-cvref<T, optional<U>> is false,
  • is_assignable_v<T&, optional<U>&> is false,
  • is_assignable_v<T&, optional<U>&&> is false,
  • is_assignable_v<T&, const optional<U>&> is false, and
  • is_assignable_v<T&, const optional<U>&&> is false.
Effects: See Table 65.
The result of the expression rhs.has_value() remains unchanged.
Table 65: optional​::​operator=(optional<U>&&) effects [tab:optional.assign.move.templ]
*this contains a value
*this does not contain a value
rhs contains a value
assigns std​::​move(*rhs) to the contained value
direct-non-list-initializes the contained value with std​::​move(*rhs)
rhs does not contain a value
destroys the contained value by calling val->T​::​~T()
no effect
Postconditions: rhs.has_value() == this->has_value().
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 state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment.
template<class... Args> constexpr T& emplace(Args&&... args);
Mandates: is_constructible_v<T, Args...> is true.
Effects: Calls *this = nullopt.
Then direct-non-list-initializes the contained value with std​::​forward​<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
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);
Constraints: is_constructible_v<T, initializer_list<U>&, Args...> is true.
Effects: Calls *this = nullopt.
Then direct-non-list-initializes the contained value with il, std​::​​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
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.

22.5.3.5 Swap [optional.swap]

constexpr void swap(optional& rhs) noexcept(see below);
Mandates: is_move_constructible_v<T> is true.
Preconditions: T meets the Cpp17Swappable requirements ([swappable.requirements]).
Effects: See Table 66.
Table 66: optional​::​swap(optional&) effects [tab:optional.swap]
*this contains a value
*this does not contain a value
rhs contains a value
calls swap(*(*this), *rhs)
direct-non-list-initializes the contained value of *this with std​::​move(*rhs), 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 the contained value of rhs with std​::​move(*(*this)), followed by val->T​::​~T(); postcondition is that *this does not contain a value and rhs contains a value
no effect
Throws: Any exceptions thrown by the operations in the relevant part of Table 66.
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 state of *val and *rhs.val is 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 state of *val and *rhs.val is determined by the exception safety guarantee of T's move constructor.

22.5.3.6 Iterator support [optional.iterators]

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().

22.5.3.7 Observers [optional.observe]

constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept;
Preconditions: *this contains a value.
Returns: val.
Remarks: These functions are constexpr functions.
constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept;
Preconditions: *this contains a value.
Returns: *val.
Remarks: These functions are constexpr functions.
constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept;
Preconditions: *this contains a value.
Effects: Equivalent to: return std​::​move(*val);
constexpr explicit operator bool() const noexcept;
Returns: true if and only if *this contains a value.
Remarks: This function is a constexpr function.
constexpr bool has_value() const noexcept;
Returns: true if and only if *this contains a value.
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 &;
Mandates: is_copy_constructible_v<T> && is_convertible_v<U&&, T> is true.
Effects: Equivalent to: return has_value() ? **this : static_cast<T>(std::forward<U>(v));
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
Mandates: is_move_constructible_v<T> && is_convertible_v<U&&, T> is true.
Effects: Equivalent to: return has_value() ? std::move(**this) : 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 &;
Let U be invoke_result_t<F, decltype(*val)>.
Mandates: remove_cvref_t<U> is a specialization of optional.
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 &&;
Let U be invoke_result_t<F, decltype(std​::​move(*val))>.
Mandates: remove_cvref_t<U> is a specialization of optional.
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 &;
Let U be remove_cv_t<invoke_result_t<F, decltype(*val)>>.
Mandates: U is a non-array object type other than in_place_t or nullopt_t.
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 non-array object type other than in_place_t or nullopt_t.
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.
Mandates: is_same_v<remove_cvref_t<invoke_result_t<F>>, optional> is true.
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.
Mandates: is_same_v<remove_cvref_t<invoke_result_t<F>>, optional> is true.
Effects: Equivalent to: if (*this) { return std::move(*this); } else { return std::forward<F>(f)(); }

22.5.3.9 Modifiers [optional.mod]

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.

22.5.4 No-value state indicator [optional.nullopt]

struct nullopt_t{see below}; inline constexpr nullopt_t nullopt(unspecified);
The struct nullopt_t is an empty class type used as a unique type to indicate the state of not containing a value for optional objects.
In particular, optional<T> has a constructor with nullopt_t as a single argument; this indicates that an optional object not containing a value shall be constructed.
Type nullopt_t shall not have a default constructor or an initializer-list constructor, and shall not be an aggregate.

22.5.5 Class bad_optional_access [optional.bad.access]

namespace std { class bad_optional_access : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
The class bad_optional_access defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

22.5.6 Relational operators [optional.relops]

template<class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
Constraints: The expression *x == *y is well-formed and its result is convertible to bool.
[Note 1:  — end note]
Returns: If x.has_value() != y.has_value(), false; otherwise if x.has_value() == false, true; otherwise *x == *y.
Remarks: Specializations of this function template for which *x == *y is a core constant expression are constexpr functions.
template<class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
Constraints: The expression *x != *y is well-formed and its result is convertible to bool.
Returns: If x.has_value() != y.has_value(), true; otherwise, if x.has_value() == false, false; otherwise *x != *y.
Remarks: Specializations of this function template for which *x != *y is a core constant expression are constexpr functions.
template<class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
Constraints: *x < *y is well-formed and its result is convertible to bool.
Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y.
Remarks: Specializations of this function template for which *x < *y is a core constant expression are constexpr functions.
template<class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
Constraints: The expression *x > *y is well-formed and its result is convertible to bool.
Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y.
Remarks: Specializations of this function template for which *x > *y is a core constant expression are constexpr functions.
template<class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
Constraints: The expression *x <= *y is well-formed and its result is convertible to bool.
Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y.
Remarks: Specializations of this function template for which *x <= *y is a core constant expression are constexpr functions.
template<class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
Constraints: The expression *x >= *y is well-formed and its result is convertible to bool.
Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y.
Remarks: Specializations of this function template for which *x >= *y is a core constant expression are constexpr functions.
template<class T, three_way_comparable_with<T> U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>& x, const optional<U>& y);
Returns: If x && y, *x <=> *y; otherwise x.has_value() <=> y.has_value().
Remarks: Specializations of this function template for which *x <=> *y is a core constant expression are constexpr functions.

22.5.7 Comparison with nullopt [optional.nullops]

template<class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
Returns: !x.
template<class T> constexpr strong_ordering operator<=>(const optional<T>& x, nullopt_t) noexcept;
Returns: x.has_value() <=> false.

22.5.8 Comparison with T [optional.comp.with.t]

template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
Constraints: U is not a specialization of optional.
The expression *x == v is well-formed and its result is convertible to bool.
[Note 1:  — end note]
Effects: Equivalent to: return x.has_value() ? *x == v : false;
template<class T, class U> constexpr bool operator==(const T& v, const optional<U>& x);
Constraints: T is not a specialization of optional.
The expression v == *x is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? v == *x : false;
template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
Constraints: U is not a specialization of optional.
The expression *x != v is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? *x != v : true;
template<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x);
Constraints: T is not a specialization of optional.
The expression v != *x is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? v != *x : true;
template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
Constraints: U is not a specialization of optional.
The expression *x < v is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? *x < v : true;
template<class T, class U> constexpr bool operator<(const T& v, const optional<U>& x);
Constraints: T is not a specialization of optional.
The expression v < *x is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? v < *x : false;
template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
Constraints: U is not a specialization of optional.
The expression *x > v is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? *x > v : false;
template<class T, class U> constexpr bool operator>(const T& v, const optional<U>& x);
Constraints: T is not a specialization of optional.
The expression v > *x is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? v > *x : true;
template<class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
Constraints: U is not a specialization of optional.
The expression *x <= v is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? *x <= v : true;
template<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x);
Constraints: T is not a specialization of optional.
The expression v <= *x is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? v <= *x : false;
template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
Constraints: U is not a specialization of optional.
The expression *x >= v is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? *x >= v : false;
template<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x);
Constraints: T is not a specialization of optional.
The expression v >= *x is well-formed and its result is convertible to bool.
Effects: Equivalent to: return x.has_value() ? v >= *x : true;
template<class T, class U> requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U> constexpr compare_three_way_result_t<T, U> operator<=>(const optional<T>& x, const U& v);
Effects: Equivalent to: return x.has_value() ? *x <=> v : strong_ordering​::​less;

22.5.9 Specialized algorithms [optional.specalg]

template<class T> constexpr void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
Constraints: is_move_constructible_v<T> is true and is_swappable_v<T> is true.
Effects: Calls x.swap(y).
template<class T> constexpr optional<decay_t<T>> make_optional(T&& v);
Returns: optional<decay_t<T>>(std​::​forward<T>(v)).
template<class T, class...Args> constexpr optional<T> make_optional(Args&&... args);
Effects: Equivalent to: return optional<T>(in_place, std​::​forward<Args>(args)...);
template<class T, class U, class... Args> constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
Effects: Equivalent to: return optional<T>(in_place, il, std​::​forward<Args>(args)...);

22.5.10 Hash support [optional.hash]

template<class T> struct hash<optional<T>>;
The specialization hash<optional<T>> is enabled ([unord.hash]) if and only if hash<remove_const_t<T>> is enabled.
When enabled, for an object o of type optional<T>, if o.has_value() == true, then hash<optional<T>>()(o) evaluates to the same value as hash<remove_const_t<T>>()(*o); otherwise it evaluates to an unspecified value.
The member functions are not guaranteed to be noexcept.

22.6 Variants [variant]

22.6.1 General [variant.general]

A variant object holds and manages the lifetime of a value.
If the variant holds a value, that value's type has to be one of the template argument types given to variant.
These template arguments are called alternatives.
In [variant], GET denotes a set of exposition-only function templates ([variant.get]).

22.6.2 Header <variant> synopsis [variant.syn]

// mostly freestanding #include <compare> // see [compare.syn] namespace std { // [variant.variant], class template variant template<class... Types> class variant; // [variant.helper], variant helper classes template<class T> struct variant_size; // not defined template<class T> struct variant_size<const T>; template<class T> constexpr size_t variant_size_v = variant_size<T>::value; template<class... Types> struct variant_size<variant<Types...>>; template<size_t I, class T> struct variant_alternative; // not defined template<size_t I, class T> struct variant_alternative<I, const T>; template<size_t I, class T> using variant_alternative_t = typename variant_alternative<I, T>::type; template<size_t I, class... Types> struct variant_alternative<I, variant<Types...>>; inline constexpr size_t variant_npos = -1; // [variant.get], value access template<class T, class... Types> constexpr bool holds_alternative(const variant<Types...>&) noexcept; template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&); // freestanding-deleted template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&); // freestanding-deleted template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&); // freestanding-deleted template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&); // freestanding-deleted template<class T, class... Types> constexpr T& get(variant<Types...>&); // freestanding-deleted template<class T, class... Types> constexpr T&& get(variant<Types...>&&); // freestanding-deleted template<class T, class... Types> constexpr const T& get(const variant<Types...>&); // freestanding-deleted template<class T, class... Types> constexpr const T&& get(const variant<Types...>&&); // freestanding-deleted template<size_t I, class... Types> constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> get_if(variant<Types...>*) noexcept; template<size_t I, class... Types> constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> get_if(const variant<Types...>*) noexcept; template<class T, class... Types> constexpr add_pointer_t<T> get_if(variant<Types...>*) noexcept; template<class T, class... Types> constexpr add_pointer_t<const T> get_if(const variant<Types...>*) noexcept; // [variant.relops], relational operators template<class... Types> constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); template<class... Types> requires (three_way_comparable<Types> && ...) constexpr common_comparison_category_t<compare_three_way_result_t<Types>...> operator<=>(const variant<Types...>&, const variant<Types...>&); // [variant.visit], visitation template<class Visitor, class... Variants> constexpr see below visit(Visitor&&, Variants&&...); template<class R, class Visitor, class... Variants> constexpr R visit(Visitor&&, Variants&&...); // [variant.monostate], class monostate struct monostate; // [variant.monostate.relops], monostate relational operators constexpr bool operator==(monostate, monostate) noexcept; constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // [variant.specalg], specialized algorithms template<class... Types> constexpr void swap(variant<Types...>&, variant<Types...>&) noexcept(see below); // [variant.bad.access], class bad_variant_access class bad_variant_access; // [variant.hash], hash support template<class T> struct hash; template<class... Types> struct hash<variant<Types...>>; template<> struct hash<monostate>; }

22.6.3 Class template variant [variant.variant]

22.6.3.1 General [variant.variant.general]

namespace std { template<class... Types> class variant { public: // [variant.ctor], constructors constexpr variant() noexcept(see below); constexpr variant(const variant&); constexpr variant(variant&&) noexcept(see below); template<class T> constexpr variant(T&&) noexcept(see below); template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args> constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...); template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&...); template<size_t I, class U, class... Args> constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...); // [variant.dtor], destructor constexpr ~variant(); // [variant.assign], assignment constexpr variant& operator=(const variant&); constexpr variant& operator=(variant&&) noexcept(see below); template<class T> constexpr variant& operator=(T&&) noexcept(see below); // [variant.mod], modifiers template<class T, class... Args> constexpr T& emplace(Args&&...); template<class T, class U, class... Args> constexpr T& emplace(initializer_list<U>, Args&&...); template<size_t I, class... Args> constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...); template<size_t I, class U, class... Args> constexpr variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...); // [variant.status], value status constexpr bool valueless_by_exception() const noexcept; constexpr size_t index() const noexcept; // [variant.swap], swap constexpr void swap(variant&) noexcept(see below); // [variant.visit], visitation template<class Self, class Visitor> constexpr decltype(auto) visit(this Self&&, Visitor&&); template<class R, class Self, class Visitor> constexpr R visit(this Self&&, Visitor&&); }; }
Any instance of variant at any given time either holds a value of one of its alternative types or holds no value.
When an instance of variant holds a value of alternative type T, it means that a value of type T, referred to as the variant object's contained value, is nested within ([intro.object]) the variant object.
All types in Types shall meet the Cpp17Destructible requirements (Table 35).
A program that instantiates the definition of variant with no template arguments is ill-formed.
If a program declares an explicit or partial specialization of variant, the program is ill-formed, no diagnostic required.

22.6.3.2 Constructors [variant.ctor]

In the descriptions that follow, let i be in the range [0, sizeof...(Types)), and be the type in Types.
constexpr variant() noexcept(see below);
Constraints: is_default_constructible_v<> is true.
Effects: Constructs a variant holding a value-initialized value of type .
Postconditions: valueless_by_exception() is false and index() is 0.
Throws: Any exception thrown by the value-initialization of .
Remarks: This function is constexpr if and only if the value-initialization of the alternative type would be constexpr-suitable ([dcl.constexpr]).
The exception specification is equivalent to is_nothrow_default_constructible_v<>.
[Note 1: 
See also class monostate.
— end note]
constexpr variant(const variant& w);
Effects: If w holds a value, initializes the variant to hold the same alternative as w and direct-initializes the contained value with GET<j>(w), where j is w.index().
Otherwise, initializes the variant to not hold a value.
Throws: Any exception thrown by direct-initializing any for all i.
Remarks: This constructor is defined as deleted unless is_copy_constructible_v<> is true for all i.
If is_trivially_copy_constructible_v<> is true for all i, this constructor is trivial.
constexpr variant(variant&& w) noexcept(see below);
Constraints: is_move_constructible_v<> is true for all i.
Effects: If w holds a value, initializes the variant to hold the same alternative as w and direct-initializes the contained value with GET<j>(std​::​move(w)), where j is w.index().
Otherwise, initializes the variant to not hold a value.
Throws: Any exception thrown by move-constructing any for all i.
Remarks: The exception specification is equivalent to the logical and of is_nothrow_move_constructible_v<> for all i.
If is_trivially_move_constructible_v<> is true for all i, this constructor is trivial.
template<class T> constexpr variant(T&& t) noexcept(see below);
Let be a type that is determined as follows: build an imaginary function FUN() for each alternative type for which x[] = {std​::​forward<T>(t)}; is well-formed for some invented variable x.
The overload FUN() selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative which is the type of the contained value after construction.
Constraints:
  • sizeof...(Types) is nonzero,
  • is_same_v<remove_cvref_t<T>, variant> is false,
  • remove_cvref_t<T> is neither a specialization of in_place_type_t nor a specialization of in_place_index_t,
  • is_constructible_v<, T> is true, and
  • the expression FUN(std​::​forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well-formed.
    [Note 2: 
    variant<string, string> v("abc"); is ill-formed, as both alternative types have an equally viable constructor for the argument.
    — end note]
Effects: Initializes *this to hold the alternative type and direct-non-list-initializes the contained value with std​::​forward<T>(t).
Postconditions: holds_alternative<>(*this) is true.
Throws: Any exception thrown by the initialization of the selected alternative .
Remarks: The exception specification is equivalent to is_nothrow_constructible_v<, T>.
If 's selected constructor is a constexpr constructor, this constructor is a constexpr constructor.
template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
Constraints:
  • There is exactly one occurrence of T in Types... and
  • is_constructible_v<T, Args...> is true.
Effects: Direct-non-list-initializes the contained value of type T with std​::​forward<Args>(args)....
Postconditions: holds_alternative<T>(*this) is true.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: If T's selected constructor is a constexpr constructor, this constructor is a constexpr constructor.
template<class T, class U, class... Args> constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Constraints:
  • There is exactly one occurrence of T in Types... and
  • is_constructible_v<T, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes the contained value of type T with il, std​::​forward<Args>(​args)....
Postconditions: holds_alternative<T>(*this) is true.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: If T's selected constructor is a constexpr constructor, this constructor is a constexpr constructor.
template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
Constraints:
  • I is less than sizeof...(Types) and
  • is_constructible_v<, Args...> is true.
Effects: Direct-non-list-initializes the contained value of type with std​::​forward<Args>(args)....
Postconditions: index() is I.
Throws: Any exception thrown by calling the selected constructor of .
Remarks: If 's selected constructor is a constexpr constructor, this constructor is a constexpr constructor.
template<size_t I, class U, class... Args> constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Constraints:
  • I is less than sizeof...(Types) and
  • is_constructible_v<, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes the contained value of type with il, std​::​forward<Args>(​args)....
Postconditions: index() is I.
Remarks: If 's selected constructor is a constexpr constructor, this constructor is a constexpr constructor.

22.6.3.3 Destructor [variant.dtor]

constexpr ~variant();
Effects: If valueless_by_exception() is false, destroys the currently contained value.
Remarks: If is_trivially_destructible_v<> is true for all , then this destructor is trivial.

22.6.3.4 Assignment [variant.assign]

constexpr variant& operator=(const variant& rhs);
Let j be rhs.index().
Effects:
  • If neither *this nor rhs holds a value, there is no effect.
  • Otherwise, if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
  • Otherwise, if index() == j, assigns the value contained in rhs to the value contained in *this.
  • Otherwise, if either is_nothrow_copy_constructible_v<> is true or is_nothrow_move_constructible_v<> is false, equivalent to emplace<j>(GET<j>(rhs)).
  • Otherwise, equivalent to operator=(variant(rhs)).
Postconditions: index() == rhs.index().
Returns: *this.
Remarks: This operator is defined as deleted unless is_copy_constructible_v<> && is_copy_assignable_v<> is true for all i.
If is_trivially_copy_constructible_v<> && is_trivially_copy_assignable_v<> && is_trivially_destructible_v<> is true for all i, this assignment operator is trivial.
constexpr variant& operator=(variant&& rhs) noexcept(see below);
Let j be rhs.index().
Constraints: is_move_constructible_v<> && is_move_assignable_v<> is true for all i.
Effects:
  • If neither *this nor rhs holds a value, there is no effect.
  • Otherwise, if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
  • Otherwise, if index() == j, assigns GET<j>(std​::​move(rhs)) to the value contained in *this.
  • Otherwise, equivalent to emplace<j>(GET<j>(std​::​move(rhs))).
Returns: *this.
Remarks: If is_trivially_move_constructible_v<> && is_trivially_move_assignable_v<> && is_trivially_destructible_v<> is true for all i, this assignment operator is trivial.
The exception specification is equivalent to is_nothrow_move_constructible_v<> && is_nothrow_move_assignable_v<> for all i.
  • If an exception is thrown during the call to 's move construction (with j being rhs.index()), the variant will hold no value.
  • If an exception is thrown during the call to 's move assignment, the state of the contained value is as defined by the exception safety guarantee of 's move assignment; index() will be j.
template<class T> constexpr variant& operator=(T&& t) noexcept(see below);
Let be a type that is determined as follows: build an imaginary function FUN() for each alternative type for which x[] = {std​::​forward<T>(t)}; is well-formed for some invented variable x.
The overload FUN() selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative which is the type of the contained value after assignment.
Constraints:
  • is_same_v<remove_cvref_t<T>, variant> is false,
  • is_assignable_v<&, T> && is_constructible_v<, T> is true, and
  • the expression FUN(std​::​forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well-formed.
    [Note 1: 
    variant<string, string> v; v = "abc"; is ill-formed, as both alternative types have an equally viable constructor for the argument.
    — end note]
Effects:
  • If *this holds a , assigns std​::​forward<T>(t) to the value contained in *this.
  • Otherwise, if is_nothrow_constructible_v<, T> || !is_nothrow_move_constructible_v<> is true, equivalent to emplace<j>(std​::​forward<T>(t)).
  • Otherwise, equivalent to emplace<j>((std​::​forward<T>(t))).
Postconditions: holds_alternative<>(*this) is true, with selected by the imaginary function overload resolution described above.
Returns: *this.
Remarks: The exception specification is equivalent to: is_nothrow_assignable_v<T&, T> && is_nothrow_constructible_v<T, T>
  • If an exception is thrown during the assignment of std​::​forward<T>(t) to the value contained in *this, the state of the contained value and t are as defined by the exception safety guarantee of the assignment expression; valueless_by_exception() will be false.
  • If an exception is thrown during the initialization of the contained value, the variant object is permitted to not hold a value.

22.6.3.5 Modifiers [variant.mod]

template<class T, class... Args> constexpr T& emplace(Args&&... args);
Constraints: is_constructible_v<T, Args...> is true, and T occurs exactly once in Types.
Effects: Equivalent to: return emplace<I>(std::forward<Args>(args)...); where I is the zero-based index of T in Types.
template<class T, class U, class... Args> constexpr T& emplace(initializer_list<U> il, Args&&... args);
Constraints: is_constructible_v<T, initializer_list<U>&, Args...> is true, and T occurs exactly once in Types.
Effects: Equivalent to: return emplace<I>(il, std::forward<Args>(args)...); where I is the zero-based index of T in Types.
template<size_t I, class... Args> constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
Mandates: I < sizeof...(Types).
Constraints: is_constructible_v<, Args...> is true.
Effects: Destroys the currently contained value if valueless_by_exception() is false.
Then direct-non-list-initializes the contained value of type with the arguments std​::​forward<Args>(args)....
Postconditions: index() is I.
Returns: A reference to the new contained value.
Throws: Any exception thrown during the initialization of the contained value.
Remarks: If an exception is thrown during the initialization of the contained value, the variant is permitted to not hold a value.
template<size_t I, class U, class... Args> constexpr variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
Mandates: I < sizeof...(Types).
Constraints: is_constructible_v<, initializer_list<U>&, Args...> is true.
Effects: Destroys the currently contained value if valueless_by_exception() is false.
Then direct-non-list-initializes the contained value of type with il, std​::​forward<Args>(args)....
Postconditions: index() is I.
Returns: A reference to the new contained value.
Throws: Any exception thrown during the initialization of the contained value.
Remarks: If an exception is thrown during the initialization of the contained value, the variant is permitted to not hold a value.

22.6.3.6 Value status [variant.status]

constexpr bool valueless_by_exception() const noexcept;
Effects: Returns false if and only if the variant holds a value.
[Note 1: 
It is possible for a variant to hold no value if an exception is thrown during a type-changing assignment or emplacement.
The latter means that even a variant<float, int> can become valueless_by_exception(), for instance by struct S { operator int() { throw 42; }}; variant<float, int> v{12.f}; v.emplace<1>(S());
— end note]
constexpr size_t index() const noexcept;
Effects: If valueless_by_exception() is true, returns variant_npos.
Otherwise, returns the zero-based index of the alternative of the contained value.

22.6.3.7 Swap [variant.swap]

constexpr void swap(variant& rhs) noexcept(see below);
Mandates: is_move_constructible_v<> is true for all i.
Preconditions: Each meets the Cpp17Swappable requirements ([swappable.requirements]).
Effects:
  • If valueless_by_exception() && rhs.valueless_by_exception() no effect.
  • Otherwise, if index() == rhs.index(), calls swap(GET<i>(*this), GET<i>(rhs)) where i is index().
  • Otherwise, exchanges values of rhs and *this.
Throws: If index() == rhs.index(), any exception thrown by swap(GET<i>(*this), GET<i>(rhs)) with i being index().
Otherwise, any exception thrown by the move constructor of or with i being index() and j being rhs.index().
Remarks: If an exception is thrown during the call to function swap(GET<i>(*this), GET<i>(rhs)), the states of the contained values of *this and of rhs are determined by the exception safety guarantee of swap for lvalues of with i being index().
If an exception is thrown during the exchange of the values of *this and rhs, the states of the values of *this and of rhs are determined by the exception safety guarantee of variant's move constructor.
The exception specification is equivalent to the logical and of is_nothrow_move_constructible_v<> && is_nothrow_swappable_v<> for all i.

22.6.4 variant helper classes [variant.helper]

template<class T> struct variant_size;
All specializations of variant_size meet the Cpp17UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_constant<size_t, N> for some N.
template<class T> struct variant_size<const T>;
Let VS denote variant_size<T> of the cv-unqualified type T.
Then each specialization of the template meets the Cpp17UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_constant<size_t, VS​::​value>.
template<class... Types> struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
template<size_t I, class T> struct variant_alternative<I, const T>;
Let VA denote variant_alternative<I, T> of the cv-unqualified type T.
Then each specialization of the template meets the Cpp17TransformationTrait requirements ([meta.rqmts]) with a member typedef type that names the type add_const_t<VA​::​type>.
variant_alternative<I, variant<Types...>>::type
Mandates: I < sizeof...(Types).
Type: The type .

22.6.5 Value access [variant.get]

template<class T, class... Types> constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
Mandates: The type T occurs exactly once in Types.
Returns: true if index() is equal to the zero-based index of T in Types.
template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>& GET(variant<Types...>& v); // exposition only template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& GET(variant<Types...>&& v); // exposition only template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& GET(const variant<Types...>& v); // exposition only template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& GET(const variant<Types...>&& v); // exposition only
Mandates: I < sizeof...(Types).
Preconditions: v.index() is I.
Returns: A reference to the object stored in the variant.
template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v); template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v); template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>& v); template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&& v);
Mandates: I < sizeof...(Types).
Effects: If v.index() is I, returns a reference to the object stored in the variant.
Otherwise, throws an exception of type bad_variant_access.
template<class T, class... Types> constexpr T& get(variant<Types...>& v); template<class T, class... Types> constexpr T&& get(variant<Types...>&& v); template<class T, class... Types> constexpr const T& get(const variant<Types...>& v); template<class T, class... Types> constexpr const T&& get(const variant<Types...>&& v);
Mandates: The type T occurs exactly once in Types.
Effects: If v holds a value of type T, returns a reference to that value.
Otherwise, throws an exception of type bad_variant_access.
template<size_t I, class... Types> constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> get_if(variant<Types...>* v) noexcept; template<size_t I, class... Types> constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> get_if(const variant<Types...>* v) noexcept;
Mandates: I < sizeof...(Types).
Returns: A pointer to the value stored in the variant, if v != nullptr and v->index() == I.
Otherwise, returns nullptr.
template<class T, class... Types> constexpr add_pointer_t<T> get_if(variant<Types...>* v) noexcept; template<class T, class... Types> constexpr add_pointer_t<const T> get_if(const variant<Types...>* v) noexcept;
Mandates: The type T occurs exactly once in Types.
Effects: Equivalent to: return get_if<i>(v); with i being the zero-based index of T in Types.

22.6.6 Relational operators [variant.relops]

template<class... Types> constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
Constraints: GET<i>(v) == GET<i>(w) is a valid expression that is convertible to bool, for all i.
Returns: If v.index() != w.index(), false; otherwise if v.valueless_by_exception(), true; otherwise GET<i>(v) == GET<i>(w) with i being v.index().
template<class... Types> constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
Constraints: GET<i>(v) != GET<i>(w) is a valid expression that is convertible to bool, for all i.
Returns: If v.index() != w.index(), true; otherwise if v.valueless_by_exception(), false; otherwise GET<i>(v) != GET<i>(w) with i being v.index().
template<class... Types> constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
Constraints: GET<i>(v) < GET<i>(w) is a valid expression that is convertible to bool, for all i.
Returns: If w.valueless_by_exception(), false; otherwise if v.valueless_by_exception(), true; otherwise, if v.index() < w.index(), true; otherwise if v.index() > w.index(), false; otherwise GET<i>(v) < GET<i>(w) with i being v.index().
template<class... Types> constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
Constraints: GET<i>(v) > GET<i>(w) is a valid expression that is convertible to bool, for all i.
Returns: If v.valueless_by_exception(), false; otherwise if w.valueless_by_exception(), true; otherwise, if v.index() > w.index(), true; otherwise if v.index() < w.index(), false; otherwise GET<i>(v) > GET<i>(w) with i being v.index().
template<class... Types> constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
Constraints: GET<i>(v) <= GET<i>(w) is a valid expression that is convertible to bool, for all i.
Returns: If v.valueless_by_exception(), true; otherwise if w.valueless_by_exception(), false; otherwise, if v.index() < w.index(), true; otherwise if v.index() > w.index(), false; otherwise GET<i>(v) <= GET<i>(w) with i being v.index().
template<class... Types> constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
Constraints: GET<i>(v) >= GET<i>(w) is a valid expression that is convertible to bool, for all i.
Returns: If w.valueless_by_exception(), true; otherwise if v.valueless_by_exception(), false; otherwise, if v.index() > w.index(), true; otherwise if v.index() < w.index(), false; otherwise GET<i>(v) >= GET<i>(w) with i being v.index().
template<class... Types> requires (three_way_comparable<Types> && ...) constexpr common_comparison_category_t<compare_three_way_result_t<Types>...> operator<=>(const variant<Types...>& v, const variant<Types...>& w);
Effects: Equivalent to: if (v.valueless_by_exception() && w.valueless_by_exception()) return strong_ordering::equal; if (v.valueless_by_exception()) return strong_ordering::less; if (w.valueless_by_exception()) return strong_ordering::greater; if (auto c = v.index() <=> w.index(); c != 0) return c; return GET<i>(v) <=> GET<i>(w); with i being v.index().

22.6.7 Visitation [variant.visit]

template<class Visitor, class... Variants> constexpr see below visit(Visitor&& vis, Variants&&... vars); template<class R, class Visitor, class... Variants> constexpr R visit(Visitor&& vis, Variants&&... vars);
Let as-variant denote the following exposition-only function templates: template<class... Ts> constexpr auto&& as-variant(variant<Ts...>& var) { return var; } template<class... Ts> constexpr auto&& as-variant(const variant<Ts...>& var) { return var; } template<class... Ts> constexpr auto&& as-variant(variant<Ts...>&& var) { return std::move(var); } template<class... Ts> constexpr auto&& as-variant(const variant<Ts...>&& var) { return std::move(var); }
Let n be sizeof...(Variants).
For each , let denote the type
decltype(as-variant(std​::​forward<>())).
Constraints: is a valid type for all .
Let V denote the pack of types .
Let m be a pack of n values of type size_t.
Such a pack is valid if
for all .
For each valid pack m, let e(m) denote the expression: INVOKE(std::forward<Visitor>(vis), GET<m>(std::forward<V>(vars))...) // see [func.require] for the first form and INVOKE<R>(std::forward<Visitor>(vis), GET<m>(std::forward<V>(vars))...) // see [func.require] for the second form.
Mandates: For each valid pack m, e(m) is a valid expression.
All such expressions are of the same type and value category.
Returns: e(m), where m is the pack for which is as-variant(vars).index() for all .
The return type is decltype(e(m)) for the first form.
Throws: bad_variant_access if (as-variant(vars).valueless_by_exception() || ...) is true.
Complexity: For n  ≤ 1, the invocation of the callable object is implemented in constant time, i.e., for , it does not depend on the number of alternative types of .
For , the invocation of the callable object has no complexity requirements.
template<class Self, class Visitor> constexpr decltype(auto) visit(this Self&& self, Visitor&& vis);
Let V be OVERRIDE_REF(Self&&, COPY_CONST(remove_reference_t<Self>, variant)) ([forward]).
Constraints: The call to visit does not use an explicit template-argument-list that begins with a type template-argument.
Effects: Equivalent to: return std​::​visit(std​::​forward<Visitor>(vis), (V)self);
template<class R, class Self, class Visitor> constexpr R visit(this Self&& self, Visitor&& vis);
Let V be OVERRIDE_REF(Self&&, COPY_CONST(remove_reference_t<Self>, variant)) ([forward]).
Effects: Equivalent to: return std​::​visit<R>(std​::​forward<Visitor>(vis), (V)self);

22.6.8 Class monostate [variant.monostate]

struct monostate{};
The class monostate can serve as a first alternative type for a variant to make the variant type default constructible.

22.6.9 monostate relational operators [variant.monostate.relops]

constexpr bool operator==(monostate, monostate) noexcept { return true; } constexpr strong_ordering operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; }
[Note 1: 
monostate objects have only a single state; they thus always compare equal.
— end note]

22.6.10 Specialized algorithms [variant.specalg]

template<class... Types> constexpr void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
Constraints: is_move_constructible_v<> && is_swappable_v<> is true for all i.
Effects: Equivalent to v.swap(w).
Remarks: The exception specification is equivalent to noexcept(v.swap(w)).

22.6.11 Class bad_variant_access [variant.bad.access]

namespace std { class bad_variant_access : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
Objects of type bad_variant_access are thrown to report invalid accesses to the value of a variant object.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

22.6.12 Hash support [variant.hash]

template<class... Types> struct hash<variant<Types...>>;
The specialization hash<variant<Types...>> is enabled ([unord.hash]) if and only if every specialization in hash<remove_const_t<Types>>... is enabled.
The member functions are not guaranteed to be noexcept.
template<> struct hash<monostate>;
The specialization is enabled ([unord.hash]).

22.7 Storage for any type [any]

22.7.1 General [any.general]

Subclause [any] describes components that C++ programs may use to perform operations on objects of a discriminated type.
[Note 1: 
The discriminated type can contain values of different types but does not attempt conversion between them, i.e., 5 is held strictly as an int and is not implicitly convertible either to "5" or to 5.0.
This indifference to interpretation but awareness of type effectively allows safe, generic containers of single values, with no scope for surprises from ambiguous conversions.
— end note]

22.7.2 Header <any> synopsis [any.synop]

namespace std { // [any.bad.any.cast], class bad_any_cast class bad_any_cast; // [any.class], class any class any; // [any.nonmembers], non-member functions void swap(any& x, any& y) noexcept; template<class T, class... Args> any make_any(Args&&... args); template<class T, class U, class... Args> any make_any(initializer_list<U> il, Args&&... args); template<class T> T any_cast(const any& operand); template<class T> T any_cast(any& operand); template<class T> T any_cast(any&& operand); template<class T> const T* any_cast(const any* operand) noexcept; template<class T> T* any_cast(any* operand) noexcept; }

22.7.3 Class bad_any_cast [any.bad.any.cast]

namespace std { class bad_any_cast : public bad_cast { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
Objects of type bad_any_cast are thrown by a failed any_cast.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

22.7.4 Class any [any.class]

22.7.4.1 General [any.class.general]

namespace std { class any { public: // [any.cons], construction and destruction constexpr any() noexcept; any(const any& other); any(any&& other) noexcept; template<class T> any(T&& value); template<class T, class... Args> explicit any(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args> explicit any(in_place_type_t<T>, initializer_list<U>, Args&&...); ~any(); // [any.assign], assignments any& operator=(const any& rhs); any& operator=(any&& rhs) noexcept; template<class T> any& operator=(T&& rhs); // [any.modifiers], modifiers template<class T, class... Args> decay_t<T>& emplace(Args&&...); template<class T, class U, class... Args> decay_t<T>& emplace(initializer_list<U>, Args&&...); void reset() noexcept; void swap(any& rhs) noexcept; // [any.observers], observers bool has_value() const noexcept; const type_info& type() const noexcept; }; }
An object of class any stores an instance of any type that meets the constructor requirements or it has no value, and this is referred to as the state of the class any object.
The stored instance is called the contained value.
Two states are equivalent if either they both have no value, or they both have a value and the contained values are equivalent.
The non-member any_cast functions provide type-safe access to the contained value.
Implementations should avoid the use of dynamically allocated memory for a small contained value.
However, any such small-object optimization shall only be applied to types T for which is_nothrow_move_constructible_v<T> is true.
[Example 1: 
A contained value of type int could be stored in an internal buffer, not in separately-allocated memory.
— end example]

22.7.4.2 Construction and destruction [any.cons]

constexpr any() noexcept;
Postconditions: has_value() is false.
any(const any& other);
Effects: If other.has_value() is false, constructs an object that has no value.
Otherwise, equivalent to any(in_place_type<T>, any_cast<const T&>(other)) where T is the type of the contained value.
Throws: Any exceptions arising from calling the selected constructor for the contained value.
any(any&& other) noexcept;
Effects: If other.has_value() is false, constructs an object that has no value.
Otherwise, constructs an object of type any that contains either the contained value of other, or contains an object of the same type constructed from the contained value of other considering that contained value as an rvalue.
template<class T> any(T&& value);
Let VT be decay_t<T>.
Constraints: VT is not the same type as any, VT is not a specialization of in_place_type_t, and is_copy_constructible_v<VT> is true.
Preconditions: VT meets the Cpp17CopyConstructible requirements.
Effects: Constructs an object of type any that contains an object of type VT direct-initialized with std​::​forward<T>(value).
Throws: Any exception thrown by the selected constructor of VT.
template<class T, class... Args> explicit any(in_place_type_t<T>, Args&&... args);
Let VT be decay_t<T>.
Constraints: is_copy_constructible_v<VT> is true and is_constructible_v<VT, Args...> is true.
Preconditions: VT meets the Cpp17CopyConstructible requirements.
Effects: Direct-non-list-initializes the contained value of type VT with std​::​forward<Args>(args)....
Postconditions: *this contains a value of type VT.
Throws: Any exception thrown by the selected constructor of VT.
template<class T, class U, class... Args> explicit any(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Let VT be decay_t<T>.
Constraints: is_copy_constructible_v<VT> is true and is_constructible_v<VT, initializer_list<U>&, Args...> is true.
Preconditions: VT meets the Cpp17CopyConstructible requirements.
Effects: Direct-non-list-initializes the contained value of type VT with il, std​::​forward<Args>(​args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of VT.
~any();
Effects: As if by reset().

22.7.4.3 Assignment [any.assign]

any& operator=(const any& rhs);
Effects: As if by any(rhs).swap(*this).
No effects if an exception is thrown.
Returns: *this.
Throws: Any exceptions arising from the copy constructor for the contained value.
any& operator=(any&& rhs) noexcept;
Effects: As if by any(std​::​move(rhs)).swap(*this).
Postconditions: The state of *this is equivalent to the original state of rhs.
Returns: *this.
template<class T> any& operator=(T&& rhs);
Let VT be decay_t<T>.
Constraints: VT is not the same type as any and is_copy_constructible_v<VT> is true.
Preconditions: VT meets the Cpp17CopyConstructible requirements.
Effects: Constructs an object tmp of type any that contains an object of type VT direct-initialized with std​::​forward<T>(rhs), and tmp.swap(*this).
No effects if an exception is thrown.
Returns: *this.
Throws: Any exception thrown by the selected constructor of VT.

22.7.4.4 Modifiers [any.modifiers]

template<class T, class... Args> decay_t<T>& emplace(Args&&... args);
Let VT be decay_t<T>.
Constraints: is_copy_constructible_v<VT> is true and is_constructible_v<VT, Args...> is true.
Preconditions: VT meets the Cpp17CopyConstructible requirements.
Effects: Calls reset().
Then direct-non-list-initializes the contained value of type VT with std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed.
template<class T, class U, class... Args> decay_t<T>& emplace(initializer_list<U> il, Args&&... args);
Let VT be decay_t<T>.
Constraints: is_copy_constructible_v<VT> is true and is_constructible_v<VT, initializer_list<U>&, Args...> is true.
Preconditions: VT meets the Cpp17CopyConstructible requirements.
Effects: Calls reset().
Then direct-non-list-initializes the contained value of type VT with il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed.
void reset() noexcept;
Effects: If has_value() is true, destroys the contained value.
Postconditions: has_value() is false.
void swap(any& rhs) noexcept;
Effects: Exchanges the states of *this and rhs.

22.7.4.5 Observers [any.observers]

bool has_value() const noexcept;
Returns: true if *this contains an object, otherwise false.
const type_info& type() const noexcept;
Returns: typeid(T) if *this has a contained value of type T, otherwise typeid(void).
[Note 1: 
Useful for querying against types known either at compile time or only at runtime.
— end note]

22.7.5 Non-member functions [any.nonmembers]

void swap(any& x, any& y) noexcept;
Effects: Equivalent to x.swap(y).
template<class T, class... Args> any make_any(Args&&... args);
Effects: Equivalent to: return any(in_place_type<T>, std​::​forward<Args>(args)...);
template<class T, class U, class... Args> any make_any(initializer_list<U> il, Args&&... args);
Effects: Equivalent to: return any(in_place_type<T>, il, std​::​forward<Args>(args)...);
template<class T> T any_cast(const any& operand); template<class T> T any_cast(any& operand); template<class T> T any_cast(any&& operand);
Let U be the type remove_cvref_t<T>.
Mandates: For the first overload, is_constructible_v<T, const U&> is true.
For the second overload, is_constructible_v<T, U&> is true.
For the third overload, is_constructible_v<T, U> is true.
Returns: For the first and second overload, static_cast<T>(*any_cast<U>(&operand)).
For the third overload, static_cast<T>(std​::​move(*any_cast<U>(&operand))).
Throws: bad_any_cast if operand.type() != typeid(remove_reference_t<T>).
[Example 1: any x(5); // x holds int assert(any_cast<int>(x) == 5); // cast to value any_cast<int&>(x) = 10; // cast to reference assert(any_cast<int>(x) == 10); x = "Meow"; // x holds const char* assert(strcmp(any_cast<const char*>(x), "Meow") == 0); any_cast<const char*&>(x) = "Harry"; assert(strcmp(any_cast<const char*>(x), "Harry") == 0); x = string("Meow"); // x holds string string s, s2("Jane"); s = move(any_cast<string&>(x)); // move from any assert(s == "Meow"); any_cast<string&>(x) = move(s2); // move to any assert(any_cast<const string&>(x) == "Jane"); string cat("Meow"); const any y(cat); // const y holds string assert(any_cast<const string&>(y) == cat); any_cast<string&>(y); // error: cannot any_cast away const — end example]
template<class T> const T* any_cast(const any* operand) noexcept; template<class T> T* any_cast(any* operand) noexcept;
Mandates: is_void_v<T> is false.
Returns: If operand != nullptr && operand->type() == typeid(T) is true, a pointer to the object contained by operand; otherwise, nullptr.
[Example 2: bool is_string(const any& operand) { return any_cast<string>(&operand) != nullptr; } — end example]

22.8 Expected objects [expected]

22.8.1 General [expected.general]

Subclause [expected] describes the class template expected that represents expected objects.
An expected<T, E> object holds an object of type T or an object of type E and manages the lifetime of the contained objects.

22.8.2 Header <expected> synopsis [expected.syn]

// mostly freestanding namespace std { // [expected.unexpected], class template unexpected template<class E> class unexpected; // [expected.bad], class template bad_expected_access template<class E> class bad_expected_access; // [expected.bad.void], specialization for void template<> class bad_expected_access<void>; // in-place construction of unexpected values struct unexpect_t { explicit unexpect_t() = default; }; inline constexpr unexpect_t unexpect{}; // [expected.expected], class template expected template<class T, class E> class expected; // partially freestanding // [expected.void], partial specialization of expected for void types template<class T, class E> requires is_void_v<T> class expected<T, E>; // partially freestanding }

22.8.3 Class template unexpected [expected.unexpected]

22.8.3.1 General [expected.un.general]

Subclause [expected.unexpected] describes the class template unexpected that represents unexpected objects stored in expected objects.
namespace std { template<class E> class unexpected { public: // [expected.un.cons], constructors constexpr unexpected(const unexpected&) = default; constexpr unexpected(unexpected&&) = default; template<class Err = E> constexpr explicit unexpected(Err&&); template<class... Args> constexpr explicit unexpected(in_place_t, Args&&...); template<class U, class... Args> constexpr explicit unexpected(in_place_t, initializer_list<U>, Args&&...); constexpr unexpected& operator=(const unexpected&) = default; constexpr unexpected& operator=(unexpected&&) = default; constexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; constexpr void swap(unexpected& other) noexcept(see below); template<class E2> friend constexpr bool operator==(const unexpected&, const unexpected<E2>&); friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y))); private: E unex; // exposition only }; template<class E> unexpected(E) -> unexpected<E>; }
A program that instantiates the definition of unexpected for a non-object type, an array type, a specialization of unexpected, or a cv-qualified type is ill-formed.

22.8.3.2 Constructors [expected.un.cons]

template<class Err = E> constexpr explicit unexpected(Err&& e);
Constraints:
  • is_same_v<remove_cvref_t<Err>, unexpected> is false; and
  • is_same_v<remove_cvref_t<Err>, in_place_t> is false; and
  • is_constructible_v<E, Err> is true.
Effects: Direct-non-list-initializes unex with std​::​forward<Err>(e).
Throws: Any exception thrown by the initialization of unex.
template<class... Args> constexpr explicit unexpected(in_place_t, Args&&... args);
Constraints: is_constructible_v<E, Args...> is true.
Effects: Direct-non-list-initializes unex with std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of unex.
template<class U, class... Args> constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args);
Constraints: is_constructible_v<E, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes unex with il, std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of unex.

22.8.3.3 Observers [expected.un.obs]

constexpr const E& error() const & noexcept; constexpr E& error() & noexcept;
Returns: unex.
constexpr E&& error() && noexcept; constexpr const E&& error() const && noexcept;
Returns: std​::​move(unex).

22.8.3.4 Swap [expected.un.swap]

constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
Mandates: is_swappable_v<E> is true.
Effects: Equivalent to: using std​::​swap; swap(unex, other.unex);
friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
Constraints: is_swappable_v<E> is true.
Effects: Equivalent to x.swap(y).

22.8.3.5 Equality operator [expected.un.eq]

template<class E2> friend constexpr bool operator==(const unexpected& x, const unexpected<E2>& y);
Mandates: The expression x.error() == y.error() is well-formed and its result is convertible to bool.
Returns: x.error() == y.error().

22.8.4 Class template bad_expected_access [expected.bad]

namespace std { template<class E> class bad_expected_access : public bad_expected_access<void> { public: explicit bad_expected_access(E); const char* what() const noexcept override; E& error() & noexcept; const E& error() const & noexcept; E&& error() && noexcept; const E&& error() const && noexcept; private: E unex; // exposition only }; }
The class template bad_expected_access defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an expected<T, E> object for which has_value() is false.
explicit bad_expected_access(E e);
Effects: Initializes unex with std​::​move(e).
const E& error() const & noexcept; E& error() & noexcept;
Returns: unex.
E&& error() && noexcept; const E&& error() const && noexcept;
Returns: std​::​move(unex).
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

22.8.5 Class template specialization bad_expected_access<void> [expected.bad.void]

namespace std { template<> class bad_expected_access<void> : public exception { protected: bad_expected_access() noexcept; bad_expected_access(const bad_expected_access&) noexcept; bad_expected_access(bad_expected_access&&) noexcept; bad_expected_access& operator=(const bad_expected_access& noexcept); bad_expected_access& operator=(bad_expected_access&&) noexcept; ~bad_expected_access(); public: const char* what() const noexcept override; }; }
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

22.8.6 Class template expected [expected.expected]

22.8.6.1 General [expected.object.general]

namespace std { template<class T, class E> class expected { public: using value_type = T; using error_type = E; using unexpected_type = unexpected<E>; template<class U> using rebind = expected<U, error_type>; // [expected.object.cons], constructors constexpr expected(); constexpr expected(const expected&); constexpr expected(expected&&) noexcept(see below); template<class U, class G> constexpr explicit(see below) expected(const expected<U, G>&); template<class U, class G> constexpr explicit(see below) expected(expected<U, G>&&); template<class U = remove_cv_t<T>> constexpr explicit(see below) expected(U&& v); template<class G> constexpr explicit(see below) expected(const unexpected<G>&); template<class G> constexpr explicit(see below) expected(unexpected<G>&&); template<class... Args> constexpr explicit expected(in_place_t, Args&&...); template<class U, class... Args> constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...); template<class... Args> constexpr explicit expected(unexpect_t, Args&&...); template<class U, class... Args> constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...); // [expected.object.dtor], destructor constexpr ~expected(); // [expected.object.assign], assignment constexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(see below); template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&); template<class G> constexpr expected& operator=(const unexpected<G>&); template<class G> constexpr expected& operator=(unexpected<G>&&); template<class... Args> constexpr T& emplace(Args&&...) noexcept; template<class U, class... Args> constexpr T& emplace(initializer_list<U>, Args&&...) noexcept; // [expected.object.swap], swap constexpr void swap(expected&) noexcept(see below); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); // [expected.object.obs], observers constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr const T&& operator*() const && noexcept; constexpr T&& operator*() && 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 const T&& value() const &&; // freestanding-deleted constexpr T&& value() &&; // freestanding-deleted constexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; 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&&) &&; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; // [expected.object.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 or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(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 auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; // [expected.object.eq], equality operators template<class T2, class E2> requires (!is_void_v<T2>) friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y); template<class T2> friend constexpr bool operator==(const expected&, const T2&); template<class E2> friend constexpr bool operator==(const expected&, const unexpected<E2>&); private: bool has_val; // exposition only union { T val; // exposition only E unex; // exposition only }; }; }
Any object of type expected<T, E> either contains a value of type T or a value of type E nested within ([intro.object]) it.
Member has_val indicates whether the expected<T, E> object contains an object of type T.
A type T is a valid value type for expected, if remove_cv_t<T> is void or a complete non-array object type that is not in_place_t, unexpect_t, or a specialization of unexpected.
A program which instantiates class template expected<T, E> with an argument T that is not a valid value type for expected is ill-formed.
A program that instantiates the definition of the template expected<T, E> with a type for the E parameter that is not a valid template argument for unexpected is ill-formed.
When T is not cv void, it shall meet the Cpp17Destructible requirements (Table 35).
E shall meet the Cpp17Destructible requirements.

22.8.6.2 Constructors [expected.object.cons]

The exposition-only variable template converts-from-any-cvref defined in [optional.ctor] is used by some constructors for expected.
constexpr expected();
Constraints: is_default_constructible_v<T> is true.
Effects: Value-initializes val.
Postconditions: has_value() is true.
Throws: Any exception thrown by the initialization of val.
constexpr expected(const expected& rhs);
Effects: If rhs.has_value() is true, direct-non-list-initializes val with *rhs.
Otherwise, direct-non-list-initializes unex with rhs.error().
Postconditions: rhs.has_value() == this->has_value().
Throws: Any exception thrown by the initialization of val or unex.
Remarks: This constructor is defined as deleted unless
  • is_copy_constructible_v<T> is true and
  • is_copy_constructible_v<E> is true.
This constructor is trivial if
  • is_trivially_copy_constructible_v<T> is true and
  • is_trivially_copy_constructible_v<E> is true.
constexpr expected(expected&& rhs) noexcept(see below);
Constraints:
  • is_move_constructible_v<T> is true and
  • is_move_constructible_v<E> is true.
Effects: If rhs.has_value() is true, direct-non-list-initializes val with std​::​move(*rhs).
Otherwise, direct-non-list-initializes unex with std​::​move(rhs.error()).
Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
Throws: Any exception thrown by the initialization of val or unex.
Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>.
This constructor is trivial if
  • is_trivially_move_constructible_v<T> is true and
  • is_trivially_move_constructible_v<E> is true.
template<class U, class G> constexpr explicit(see below) expected(const expected<U, G>& rhs); template<class U, class G> constexpr explicit(see below) expected(expected<U, G>&& rhs);
Let:
  • UF be const U& for the first overload and U for the second overload.
  • GF be const G& for the first overload and G for the second overload.
Constraints:
  • is_constructible_v<T, UF> is true; and
  • is_constructible_v<E, GF> is true; and
  • if T is not cv bool, converts-from-any-cvref<T, expected<U, G>> is false; and
  • is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
  • is_constructible_v<unexpected<E>, expected<U, G>> is false; and
  • is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
  • is_constructible_v<unexpected<E>, const expected<U, G>> is false.
Effects: If rhs.has_value(), direct-non-list-initializes val with std​::​forward<UF>(*rhs).
Otherwise, direct-non-list-initializes unex with std​::​forward<GF>(rhs.error()).
Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
Throws: Any exception thrown by the initialization of val or unex.
Remarks: The expression inside explicit is equivalent to !is_convertible_v<UF, T> || !is_convertible_v<GF, E>.
template<class U = remove_cv_t<T>> constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
Constraints:
  • is_same_v<remove_cvref_t<U>, in_place_t> is false; and
  • is_same_v<expected, remove_cvref_t<U>> is false; and
  • remove_cvref_t<U> is not a specialization of unexpected; and
  • is_constructible_v<T, U> is true; and
  • if T is cv bool, remove_cvref_t<U> is not a specialization of expected.
Effects: Direct-non-list-initializes val with std​::​forward<U>(v).
Postconditions: has_value() is true.
Throws: Any exception thrown by the initialization of val.
template<class G> constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e); template<class G> constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
Let GF be const G& for the first overload and G for the second overload.
Constraints: is_constructible_v<E, GF> is true.
Effects: Direct-non-list-initializes unex with std​::​forward<GF>(e.error()).
Postconditions: has_value() is false.
Throws: Any exception thrown by the initialization of unex.
template<class... Args> constexpr explicit expected(in_place_t, Args&&... args);
Constraints: is_constructible_v<T, Args...> is true.
Effects: Direct-non-list-initializes val with std​::​forward<Args>(args)....
Postconditions: has_value() is true.
Throws: Any exception thrown by the initialization of val.
template<class U, class... Args> constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
Constraints: is_constructible_v<T, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes val with il, std​::​forward<Args>(args)....
Postconditions: has_value() is true.
Throws: Any exception thrown by the initialization of val.
template<class... Args> constexpr explicit expected(unexpect_t, Args&&... args);
Constraints: is_constructible_v<E, Args...> is true.
Effects: Direct-non-list-initializes unex with std​::​forward<Args>(args)....
Postconditions: has_value() is false.
Throws: Any exception thrown by the initialization of unex.
template<class U, class... Args> constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
Constraints: is_constructible_v<E, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes unex with il, std​::​forward<Args>(args)....
Postconditions: has_value() is false.
Throws: Any exception thrown by the initialization of unex.

22.8.6.3 Destructor [expected.object.dtor]

constexpr ~expected();
Effects: If has_value() is true, destroys val, otherwise destroys unex.
Remarks: If is_trivially_destructible_v<T> is true, and is_trivially_destructible_v<E> is true, then this destructor is a trivial destructor.

22.8.6.4 Assignment [expected.object.assign]

This subclause makes use of the following exposition-only function template: template<class T, class U, class... Args> constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { // exposition only if constexpr (is_nothrow_constructible_v<T, Args...>) { destroy_at(addressof(oldval)); construct_at(addressof(newval), std::forward<Args>(args)...); } else if constexpr (is_nothrow_move_constructible_v<T>) { T tmp(std::forward<Args>(args)...); destroy_at(addressof(oldval)); construct_at(addressof(newval), std::move(tmp)); } else { U tmp(std::move(oldval)); destroy_at(addressof(oldval)); try { construct_at(addressof(newval), std::forward<Args>(args)...); } catch (...) { construct_at(addressof(oldval), std::move(tmp)); throw; } } }
constexpr expected& operator=(const expected& rhs);
Effects:
  • If this->has_value() && rhs.has_value() is true, equivalent to val = *rhs.
  • Otherwise, if this->has_value() is true, equivalent to: reinit-expected(unex, val, rhs.error())
  • Otherwise, if rhs.has_value() is true, equivalent to: reinit-expected(val, unex, *rhs)
  • Otherwise, equivalent to unex = rhs.error().
Then, if no exception was thrown, equivalent to: has_val = rhs.has_value(); return *this;
Returns: *this.
Remarks: This operator is defined as deleted unless:
  • is_copy_assignable_v<T> is true and
  • is_copy_constructible_v<T> is true and
  • is_copy_assignable_v<E> is true and
  • is_copy_constructible_v<E> is true and
  • is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true.
constexpr expected& operator=(expected&& rhs) noexcept(see below);
Constraints:
  • is_move_constructible_v<T> is true and
  • is_move_assignable_v<T> is true and
  • is_move_constructible_v<E> is true and
  • is_move_assignable_v<E> is true and
  • is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true.
Effects:
  • If this->has_value() && rhs.has_value() is true, equivalent to val = std​::​move(*rhs).
  • Otherwise, if this->has_value() is true, equivalent to: reinit-expected(unex, val, std::move(rhs.error()))
  • Otherwise, if rhs.has_value() is true, equivalent to: reinit-expected(val, unex, std::move(*rhs))
  • Otherwise, equivalent to unex = std​::​move(rhs.error()).
Then, if no exception was thrown, equivalent to: has_val = rhs.has_value(); return *this;
Returns: *this.
Remarks: The exception specification is equivalent to: is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
template<class U = remove_cv_t<T>> constexpr expected& operator=(U&& v);
Constraints:
  • is_same_v<expected, remove_cvref_t<U>> is false; and
  • remove_cvref_t<U> is not a specialization of unexpected; and
  • is_constructible_v<T, U> is true; and
  • is_assignable_v<T&, U> is true; and
  • is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> ||
    is_nothrow_move_constructible_v<E>
    is true.
Effects:
  • If has_value() is true, equivalent to: val = std​::​forward<U>(v);
  • Otherwise, equivalent to: reinit-expected(val, unex, std::forward<U>(v)); has_val = true;
Returns: *this.
template<class G> constexpr expected& operator=(const unexpected<G>& e); template<class G> constexpr expected& operator=(unexpected<G>&& e);
Let GF be const G& for the first overload and G for the second overload.
Constraints:
  • is_constructible_v<E, GF> is true; and
  • is_assignable_v<E&, GF> is true; and
  • is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
    is_nothrow_move_constructible_v<E>
    is true.
Effects:
  • If has_value() is true, equivalent to: reinit-expected(unex, val, std::forward<GF>(e.error())); has_val = false;
  • Otherwise, equivalent to: unex = std​::​forward<GF>(e.error());
Returns: *this.
template<class... Args> constexpr T& emplace(Args&&... args) noexcept;
Constraints: is_nothrow_constructible_v<T, Args...> is true.
Effects: Equivalent to: if (has_value()) { destroy_at(addressof(val)); } else { destroy_at(addressof(unex)); has_val = true; } return *construct_at(addressof(val), std::forward<Args>(args)...);
template<class U, class... Args> constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept;
Constraints: is_nothrow_constructible_v<T, initializer_list<U>&, Args...> is true.
Effects: Equivalent to: if (has_value()) { destroy_at(addressof(val)); } else { destroy_at(addressof(unex)); has_val = true; } return *construct_at(addressof(val), il, std::forward<Args>(args)...);

22.8.6.5 Swap [expected.object.swap]

constexpr void swap(expected& rhs) noexcept(see below);
Constraints:
  • is_swappable_v<T> is true and
  • is_swappable_v<E> is true and
  • is_move_constructible_v<T> && is_move_constructible_v<E> is true, and
  • is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true.
Effects: See Table 67.
Table 67: swap(expected&) effects [tab:expected.object.swap]
this->has_value()
!this->has_value()
rhs.has_value()
equivalent to: using std​::​swap; swap(val, rhs.val);
calls rhs.swap(*this)
!rhs.has_value()
see below
equivalent to: using std​::​swap; swap(unex, rhs.unex);
For the case where rhs.has_value() is false and this->has_value() is true, equivalent to: if constexpr (is_nothrow_move_constructible_v<E>) { E tmp(std::move(rhs.unex)); destroy_at(addressof(rhs.unex)); try { construct_at(addressof(rhs.val), std::move(val)); destroy_at(addressof(val)); construct_at(addressof(unex), std::move(tmp)); } catch(...) { construct_at(addressof(rhs.unex), std::move(tmp)); throw; } } else { T tmp(std::move(val)); destroy_at(addressof(val)); try { construct_at(addressof(unex), std::move(rhs.unex)); destroy_at(addressof(rhs.unex)); construct_at(addressof(rhs.val), std::move(tmp)); } catch (...) { construct_at(addressof(val), std::move(tmp)); throw; } } has_val = false; rhs.has_val = true;
Throws: Any exception thrown by the expressions in the Effects.
Remarks: The exception specification is equivalent to: is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>
friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
Effects: Equivalent to x.swap(y).

22.8.6.6 Observers [expected.object.obs]

constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept;
Preconditions: has_value() is true.
Returns: addressof(val).
constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept;
Preconditions: has_value() is true.
Returns: val.
constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept;
Preconditions: has_value() is true.
Returns: std​::​move(val).
constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept;
Returns: has_val.
constexpr const T& value() const &; constexpr T& value() &;
Mandates: is_copy_constructible_v<E> is true.
Returns: val, if has_value() is true.
Throws: bad_expected_access(as_const(error())) if has_value() is false.
constexpr T&& value() &&; constexpr const T&& value() const &&;
Mandates: is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std​::​move(error()))> is true.
Returns: std​::​move(val), if has_value() is true.
Throws: bad_expected_access(std​::​move(error())) if has_value() is false.
constexpr const E& error() const & noexcept; constexpr E& error() & noexcept;
Preconditions: has_value() is false.
Returns: unex.
constexpr E&& error() && noexcept; constexpr const E&& error() const && noexcept;
Preconditions: has_value() is false.
Returns: std​::​move(unex).
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
Mandates: is_copy_constructible_v<T> is true and is_convertible_v<U, T> is true.
Returns: has_value() ? **this : static_cast<T>(std​::​forward<U>(v)).
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
Mandates: is_move_constructible_v<T> is true and is_convertible_v<U, T> is true.
Returns: has_value() ? std​::​move(**this) : static_cast<T>(std​::​forward<U>(v)).
template<class G = E> constexpr E error_or(G&& e) const &;
Mandates: is_copy_constructible_v<E> is true and is_convertible_v<G, E> is true.
Returns: std​::​forward<G>(e) if has_value() is true, error() otherwise.
template<class G = E> constexpr E error_or(G&& e) &&;
Mandates: is_move_constructible_v<E> is true and is_convertible_v<G, E> is true.
Returns: std​::​forward<G>(e) if has_value() is true, std​::​move(error()) otherwise.

22.8.6.7 Monadic operations [expected.object.monadic]

template<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) const &;
Let U be remove_cvref_t<invoke_result_t<F, decltype((val))>>.
Constraints: is_constructible_v<E, decltype(error())> is true.
Mandates: U is a specialization of expected and is_same_v<U​::​error_type, E> is true.
Effects: Equivalent to: if (has_value()) return invoke(std::forward<F>(f), val); else return U(unexpect, error());
template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &&;
Let U be remove_cvref_t<invoke_result_t<F, decltype(std​::​move(val))>>.
Constraints: is_constructible_v<E, decltype(std​::​move(error()))> is true.
Mandates: U is a specialization of expected and is_same_v<U​::​error_type, E> is true.
Effects: Equivalent to: if (has_value()) return invoke(std::forward<F>(f), std::move(val)); else return U(unexpect, std::move(error()));
template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) const &;
Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>.
Constraints: is_constructible_v<T, decltype((val))> is true.
Mandates: G is a specialization of expected and is_same_v<G​::​value_type, T> is true.
Effects: Equivalent to: if (has_value()) return G(in_place, val); else return invoke(std::forward<F>(f), error());
template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &&;
Let G be remove_cvref_t<invoke_result_t<F, decltype(std​::​move(error()))>>.
Constraints: is_constructible_v<T, decltype(std​::​move(val))> is true.
Mandates: G is a specialization of expected and is_same_v<G​::​value_type, T> is true.
Effects: Equivalent to: if (has_value()) return G(in_place, std::move(val)); else return invoke(std::forward<F>(f), std::move(error()));
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((val))>>.
Constraints: is_constructible_v<E, decltype(error())> is true.
Mandates: U is a valid value type for expected.
If is_void_v<U> is false, the declaration U u(invoke(std::forward<F>(f), val)); is well-formed.
Effects:
  • If has_value() is false, returns expected<U, E>(unexpect, error()).
  • Otherwise, if is_void_v<U> is false, returns an expected<U, E> object whose has_val member is true and val member is direct-non-list-initialized with invoke(std​::​forward<F>(f), val).
  • Otherwise, evaluates invoke(std​::​forward<F>(f), val) and then returns expected<U, E>().
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))>>.
Constraints: is_constructible_v<E, decltype(std​::​move(error()))> is true.
Mandates: U is a valid value type for expected.
If is_void_v<U> is false, the declaration U u(invoke(std::forward<F>(f), std::move(val))); is well-formed.
Effects:
  • If has_value() is false, returns expected<U, E>(unexpect, std​::​move(error())).
  • Otherwise, if is_void_v<U> is false, returns an expected<U, E> object whose has_val member is true and val member is direct-non-list-initialized with invoke(std​::​forward<F>(f), std​::​move(val)).
  • Otherwise, evaluates invoke(std​::​forward<F>(f), std​::​move(val)) and then returns expected<U, E>().
template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) const &;
Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>.
Constraints: is_constructible_v<T, decltype((val))> is true.
Mandates: G is a valid template argument for unexpected ([expected.un.general]) and the declaration G g(invoke(std::forward<F>(f), error())); is well-formed.
Returns: If has_value() is true, expected<T, G>(in_place, val); otherwise, an expected<T, G> object whose has_val member is false and unex member is direct-non-list-initialized with invoke(std​::​forward<F>(f), error()).
template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &&;
Let G be remove_cv_t<invoke_result_t<F, decltype(std​::​move(error()))>>.
Constraints: is_constructible_v<T, decltype(std​::​move(val))> is true.
Mandates: G is a valid template argument for unexpected ([expected.un.general]) and the declaration G g(invoke(std::forward<F>(f), std::move(error()))); is well-formed.
Returns: If has_value() is true, expected<T, G>(in_place, std​::​move(val)); otherwise, an expected<T, G> object whose has_val member is false and unex member is direct-non-list-initialized with invoke(std​::​forward<F>(f), std​::​move(error())).

22.8.6.8 Equality operators [expected.object.eq]

template<class T2, class E2> requires (!is_void_v<T2>) friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
Constraints: The expressions *x == *y and x.error() == y.error() are well-formed and their results are convertible to bool.
Returns: If x.has_value() does not equal y.has_value(), false; otherwise if x.has_value() is true, *x == *y; otherwise x.error() == y.error().
template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
Constraints: T2 is not a specialization of expected.
The expression *x == v is well-formed and its result is convertible to bool.
[Note 1:  — end note]
Returns: x.has_value() && static_cast<bool>(*x == v).
template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
Constraints: The expression x.error() == e.error() is well-formed and its result is convertible to bool.
Returns: !x.has_value() && static_cast<bool>(x.error() == e.error()).

22.8.7 Partial specialization of expected for void types [expected.void]

22.8.7.1 General [expected.void.general]

template<class T, class E> requires is_void_v<T> class expected<T, E> { public: using value_type = T; using error_type = E; using unexpected_type = unexpected<E>; template<class U> using rebind = expected<U, error_type>; // [expected.void.cons], constructors constexpr expected() noexcept; constexpr expected(const expected&); constexpr expected(expected&&) noexcept(see below); template<class U, class G> constexpr explicit(see below) expected(const expected<U, G>&); template<class U, class G> constexpr explicit(see below) expected(expected<U, G>&&); template<class G> constexpr explicit(see below) expected(const unexpected<G>&); template<class G> constexpr explicit(see below) expected(unexpected<G>&&); constexpr explicit expected(in_place_t) noexcept; template<class... Args> constexpr explicit expected(unexpect_t, Args&&...); template<class U, class... Args> constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...); // [expected.void.dtor], destructor constexpr ~expected(); // [expected.void.assign], assignment constexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(see below); template<class G> constexpr expected& operator=(const unexpected<G>&); template<class G> constexpr expected& operator=(unexpected<G>&&); constexpr void emplace() noexcept; // [expected.void.swap], swap constexpr void swap(expected&) noexcept(see below); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); // [expected.void.obs], observers constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr void operator*() const noexcept; constexpr void value() const &; // freestanding-deleted constexpr void value() &&; // freestanding-deleted constexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; // [expected.void.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 or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(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 auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; // [expected.void.eq], equality operators template<class T2, class E2> requires is_void_v<T2> friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y); template<class E2> friend constexpr bool operator==(const expected&, const unexpected<E2>&); private: bool has_val; // exposition only union { E unex; // exposition only }; };
Any object of type expected<T, E> either represents a value of type T, or contains a value of type E nested within ([intro.object]) it.
Member has_val indicates whether the expected<T, E> object represents a value of type T.
A program that instantiates the definition of the template expected<T, E> with a type for the E parameter that is not a valid template argument for unexpected is ill-formed.
E shall meet the requirements of Cpp17Destructible (Table 35).

22.8.7.2 Constructors [expected.void.cons]

constexpr expected() noexcept;
Postconditions: has_value() is true.
constexpr expected(const expected& rhs);
Effects: If rhs.has_value() is false, direct-non-list-initializes unex with rhs.error().
Postconditions: rhs.has_value() == this->has_value().
Throws: Any exception thrown by the initialization of unex.
Remarks: This constructor is defined as deleted unless is_copy_constructible_v<E> is true.
This constructor is trivial if is_trivially_copy_constructible_v<E> is true.
constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
Constraints: is_move_constructible_v<E> is true.
Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std​::​move(rhs.error()).
Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
Throws: Any exception thrown by the initialization of unex.
Remarks: This constructor is trivial if is_trivially_move_constructible_v<E> is true.
template<class U, class G> constexpr explicit(!is_convertible_v<const G&, E>) expected(const expected<U, G>& rhs); template<class U, class G> constexpr explicit(!is_convertible_v<G, E>) expected(expected<U, G>&& rhs);
Let GF be const G& for the first overload and G for the second overload.
Constraints:
  • is_void_v<U> is true; and
  • is_constructible_v<E, GF> is true; and
  • is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
  • is_constructible_v<unexpected<E>, expected<U, G>> is false; and
  • is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
  • is_constructible_v<unexpected<E>, const expected<U, G>> is false.
Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std​::​forward<GF>(rhs.error()).
Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
Throws: Any exception thrown by the initialization of unex.
template<class G> constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e); template<class G> constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
Let GF be const G& for the first overload and G for the second overload.
Constraints: is_constructible_v<E, GF> is true.
Effects: Direct-non-list-initializes unex with std​::​forward<GF>(e.error()).
Postconditions: has_value() is false.
Throws: Any exception thrown by the initialization of unex.
constexpr explicit expected(in_place_t) noexcept;
Postconditions: has_value() is true.
template<class... Args> constexpr explicit expected(unexpect_t, Args&&... args);
Constraints: is_constructible_v<E, Args...> is true.
Effects: Direct-non-list-initializes unex with std​::​forward<Args>(args)....
Postconditions: has_value() is false.
Throws: Any exception thrown by the initialization of unex.
template<class U, class... Args> constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
Constraints: is_constructible_v<E, initializer_list<U>&, Args...> is true.
Effects: Direct-non-list-initializes unex with il, std​::​forward<Args>(args)....
Postconditions: has_value() is false.
Throws: Any exception thrown by the initialization of unex.

22.8.7.3 Destructor [expected.void.dtor]

constexpr ~expected();
Effects: If has_value() is false, destroys unex.
Remarks: If is_trivially_destructible_v<E> is true, then this destructor is a trivial destructor.

22.8.7.4 Assignment [expected.void.assign]

constexpr expected& operator=(const expected& rhs);
Effects:
  • If this->has_value() && rhs.has_value() is true, no effects.
  • Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), rhs.unex); has_val = false;
  • Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
  • Otherwise, equivalent to unex = rhs.error().
Returns: *this.
Remarks: This operator is defined as deleted unless is_copy_assignable_v<E> is true and is_copy_constructible_v<E> is true.
constexpr expected& operator=(expected&& rhs) noexcept(see below);
Constraints: is_move_constructible_v<E> is true and is_move_assignable_v<E> is true.
Effects:
  • If this->has_value() && rhs.has_value() is true, no effects.
  • Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), std::move(rhs.unex)); has_val = false;
  • Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
  • Otherwise, equivalent to unex = std​::​move(rhs.error()).
Returns: *this.
Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>.
template<class G> constexpr expected& operator=(const unexpected<G>& e); template<class G> constexpr expected& operator=(unexpected<G>&& e);
Let GF be const G& for the first overload and G for the second overload.
Constraints: is_constructible_v<E, GF> is true and is_assignable_v<E&, GF> is true.
Effects:
  • If has_value() is true, equivalent to: construct_at(addressof(unex), std::forward<GF>(e.error())); has_val = false;
  • Otherwise, equivalent to: unex = std​::​forward<GF>(e.error());
Returns: *this.
constexpr void emplace() noexcept;
Effects: If has_value() is false, destroys unex and sets has_val to true.

22.8.7.5 Swap [expected.void.swap]

constexpr void swap(expected& rhs) noexcept(see below);
Constraints: is_swappable_v<E> is true and is_move_constructible_v<E> is true.
Effects: See Table 68.
Table 68: swap(expected&) effects [tab:expected.void.swap]
this->has_value()
!this->has_value()
rhs.has_value()
no effects
calls rhs.swap(*this)
!rhs.has_value()
see below
equivalent to: using std​::​swap; swap(unex, rhs.unex);
For the case where rhs.has_value() is false and this->has_value() is true, equivalent to: construct_at(addressof(unex), std::move(rhs.unex)); destroy_at(addressof(rhs.unex)); has_val = false; rhs.has_val = true;
Throws: Any exception thrown by the expressions in the Effects.
Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>.
friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
Effects: Equivalent to x.swap(y).

22.8.7.6 Observers [expected.void.obs]

constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept;
Returns: has_val.
constexpr void operator*() const noexcept;
Preconditions: has_value() is true.
constexpr void value() const &;
Mandates: is_copy_constructible_v<E> is true.
Throws: bad_expected_access(error()) if has_value() is false.
constexpr void value() &&;
Mandates: is_copy_constructible_v<E> is true and is_move_constructible_v<E> is true.
Throws: bad_expected_access(std​::​move(error())) if has_value() is false.
constexpr const E& error() const & noexcept; constexpr E& error() & noexcept;
Preconditions: has_value() is false.
Returns: unex.
constexpr E&& error() && noexcept; constexpr const E&& error() const && noexcept;
Preconditions: has_value() is false.
Returns: std​::​move(unex).
template<class G = E> constexpr E error_or(G&& e) const &;
Mandates: is_copy_constructible_v<E> is true and is_convertible_v<G, E> is true.
Returns: std​::​forward<G>(e) if has_value() is true, error() otherwise.
template<class G = E> constexpr E error_or(G&& e) &&;
Mandates: is_move_constructible_v<E> is true and is_convertible_v<G, E> is true.
Returns: std​::​forward<G>(e) if has_value() is true, std​::​move(error()) otherwise.

22.8.7.7 Monadic operations [expected.void.monadic]

template<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) const &;
Let U be remove_cvref_t<invoke_result_t<F>>.
Constraints: is_constructible_v<E, decltype(error())>> is true.
Mandates: U is a specialization of expected and is_same_v<U​::​error_type, E> is true.
Effects: Equivalent to: if (has_value()) return invoke(std::forward<F>(f)); else return U(unexpect, error());
template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &&;
Let U be remove_cvref_t<invoke_result_t<F>>.
Constraints: is_constructible_v<E, decltype(std​::​move(error()))> is true.
Mandates: U is a specialization of expected and is_same_v<U​::​error_type, E> is true.
Effects: Equivalent to: if (has_value()) return invoke(std::forward<F>(f)); else return U(unexpect, std::move(error()));
template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) const &;
Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>.
Mandates: G is a specialization of expected and is_same_v<G​::​value_type, T> is true.
Effects: Equivalent to: if (has_value()) return G(); else return invoke(std::forward<F>(f), error());
template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &&;
Let G be remove_cvref_t<invoke_result_t<F, decltype(std​::​move(error()))>>.
Mandates: G is a specialization of expected and is_same_v<G​::​value_type, T> is true.
Effects: Equivalent to: if (has_value()) return G(); else return invoke(std::forward<F>(f), std::move(error()));
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>>.
Constraints: is_constructible_v<E, decltype(error())> is true.
Mandates: U is a valid value type for expected.
If is_void_v<U> is false, the declaration U u(invoke(std::forward<F>(f))); is well-formed.
Effects:
  • If has_value() is false, returns expected<U, E>(unexpect, error()).
  • Otherwise, if is_void_v<U> is false, returns an expected<U, E> object whose has_val member is true and val member is direct-non-list-initialized with invoke(std​::​forward<F>(f)).
  • Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returns expected<U, E>().
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>>.
Constraints: is_constructible_v<E, decltype(std​::​move(error()))> is true.
Mandates: U is a valid value type for expected.
If is_void_v<U> is false, the declaration U u(invoke(std::forward<F>(f))); is well-formed.
Effects:
  • If has_value() is false, returns expected<U, E>(unexpect, std​::​move(error())).
  • Otherwise, if is_void_v<U> is false, returns an expected<U, E> object whose has_val member is true and val member is direct-non-list-initialized with invoke(std​::​forward<F>(f)).
  • Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returns expected<U, E>().
template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) const &;
Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>.
Mandates: G is a valid template argument for unexpected ([expected.un.general]) and the declaration G g(invoke(std::forward<F>(f), error())); is well-formed.
Returns: If has_value() is true, expected<T, G>(); otherwise, an expected<T, G> object whose has_val member is false and unex member is direct-non-list-initialized with invoke(std​::​forward<F>(f), error()).
template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &&;
Let G be remove_cv_t<invoke_result_t<F, decltype(std​::​move(error()))>>.
Mandates: G is a valid template argument for unexpected ([expected.un.general]) and the declaration G g(invoke(std::forward<F>(f), std::move(error()))); is well-formed.
Returns: If has_value() is true, expected<T, G>(); otherwise, an expected<T, G> object whose has_val member is false and unex member is direct-non-list-initialized with invoke(std​::​forward<F>(f), std​::​move(error())).

22.8.7.8 Equality operators [expected.void.eq]

template<class T2, class E2> requires is_void_v<T2> friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
Constraints: The expression x.error() == y.error() is well-formed and its result is convertible to bool.
Returns: If x.has_value() does not equal y.has_value(), false; otherwise x.has_value() || static_cast<bool>(x.error() == y.error()).
template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
Constraints: The expression x.error() == e.error() is well-formed and its result is convertible to bool.
Returns: !x.has_value() && static_cast<bool>(x.error() == e.error()).

22.9 Bitsets [bitset]

22.9.1 Header <bitset> synopsis [bitset.syn]

The header <bitset> defines a class template and several related functions for representing and manipulating fixed-size sequences of bits.
#include <string> // see [string.syn] #include <iosfwd> // for istream ([istream.syn]), ostream ([ostream.syn]), see [iosfwd.syn] namespace std { template<size_t N> class bitset; // [bitset.operators], bitset operators template<size_t N> constexpr bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept; template<size_t N> constexpr bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept; template<size_t N> constexpr bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept; template<class charT, class traits, size_t N> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, bitset<N>& x); template<class charT, class traits, size_t N> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x); }

22.9.2 Class template bitset [template.bitset]

22.9.2.1 General [template.bitset.general]

namespace std { template<size_t N> class bitset { public: // bit reference class reference { public: constexpr reference(const reference&) = default; constexpr ~reference(); constexpr reference& operator=(bool x) noexcept; // for b[i] = x; constexpr reference& operator=(const reference&) noexcept; // for b[i] = b[j]; constexpr bool operator~() const noexcept; // flips the bit constexpr operator bool() const noexcept; // for x = b[i]; constexpr reference& flip() noexcept; // for b[i].flip(); }; // [bitset.cons], constructors constexpr bitset() noexcept; constexpr bitset(unsigned long long val) noexcept; template<class charT, class traits, class Allocator> constexpr explicit bitset( const basic_string<charT, traits, Allocator>& str, typename basic_string<charT, traits, Allocator>::size_type pos = 0, typename basic_string<charT, traits, Allocator>::size_type n = basic_string<charT, traits, Allocator>::npos, charT zero = charT('0'), charT one = charT('1')); template<class charT, class traits> constexpr explicit bitset( basic_string_view<charT, traits> str, typename basic_string_view<charT, traits>::size_type pos = 0, typename basic_string_view<charT, traits>::size_type n = basic_string_view<charT, traits>::npos, charT zero = charT('0'), charT one = charT('1')); template<class charT> constexpr explicit bitset( const charT* str, typename basic_string_view<charT>::size_type n = basic_string_view<charT>::npos, charT zero = charT('0'), charT one = charT('1')); // [bitset.members], bitset operations constexpr bitset& operator&=(const bitset& rhs) noexcept; constexpr bitset& operator|=(const bitset& rhs) noexcept; constexpr bitset& operator^=(const bitset& rhs) noexcept; constexpr bitset& operator<<=(size_t pos) noexcept; constexpr bitset& operator>>=(size_t pos) noexcept; constexpr bitset operator<<(size_t pos) const noexcept; constexpr bitset operator>>(size_t pos) const noexcept; constexpr bitset& set() noexcept; constexpr bitset& set(size_t pos, bool val = true); constexpr bitset& reset() noexcept; constexpr bitset& reset(size_t pos); constexpr bitset operator~() const noexcept; constexpr bitset& flip() noexcept; constexpr bitset& flip(size_t pos); // element access constexpr bool operator[](size_t pos) const; constexpr reference operator[](size_t pos); constexpr unsigned long to_ulong() const; constexpr unsigned long long to_ullong() const; template<class charT = char, class traits = char_traits<charT>, class Allocator = allocator<charT>> constexpr basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const; // observers constexpr size_t count() const noexcept; constexpr size_t size() const noexcept; constexpr bool operator==(const bitset& rhs) const noexcept; constexpr bool test(size_t pos) const; constexpr bool all() const noexcept; constexpr bool any() const noexcept; constexpr bool none() const noexcept; }; // [bitset.hash], hash support template<class T> struct hash; template<size_t N> struct hash<bitset<N>>; }
The class template bitset<N> describes an object that can store a sequence consisting of a fixed number of bits, N.
Each bit represents either the value zero (reset) or one (set).
To toggle a bit is to change the value zero to one, or the value one to zero.
Each bit has a non-negative position pos.
When converting between an object of class bitset<N> and a value of some integral type, bit position pos corresponds to the bit value 1 << pos.
The integral value corresponding to two or more bits is the sum of their bit values.
The functions described in [template.bitset] can report three kinds of errors, each associated with a distinct exception:

22.9.2.2 Constructors [bitset.cons]

constexpr bitset() noexcept;
Effects: Initializes all bits in *this to zero.
constexpr bitset(unsigned long long val) noexcept;
Effects: Initializes the first M bit positions to the corresponding bit values in val.
M is the smaller of N and the number of bits in the value representation ([basic.types.general]) of unsigned long long.
If M < N, the remaining bit positions are initialized to zero.
template<class charT, class traits, class Allocator> constexpr explicit bitset( const basic_string<charT, traits, Allocator>& str, typename basic_string<charT, traits, Allocator>::size_type pos = 0, typename basic_string<charT, traits, Allocator>::size_type n = basic_string<charT, traits, Allocator>::npos, charT zero = charT('0'), charT one = charT('1')); template<class charT, class traits> constexpr explicit bitset( basic_string_view<charT, traits> str, typename basic_string_view<charT, traits>::size_type pos = 0, typename basic_string_view<charT, traits>::size_type n = basic_string_view<charT, traits>::npos, charT zero = charT('0'), charT one = charT('1'));
Effects: Determines the effective length rlen of the initializing string as the smaller of n and str.size() - pos.
Initializes the first M bit positions to values determined from the corresponding characters in the string str.
M is the smaller of N and rlen.
An element of the constructed object has value zero if the corresponding character in str, beginning at position pos, is zero.
Otherwise, the element has the value one.
Character position pos + M - 1 corresponds to bit position zero.
Subsequent decreasing character positions correspond to increasing bit positions.
If M < N, remaining bit positions are initialized to zero.
The function uses traits​::​eq to compare the character values.
Throws: out_of_range if pos > str.size() or invalid_argument if any of the rlen characters in str beginning at position pos is other than zero or one.
template<class charT> constexpr explicit bitset( const charT* str, typename basic_string_view<charT>::size_type n = basic_string_view<charT>::npos, charT zero = charT('0'), charT one = charT('1'));
Effects: As if by: bitset(n == basic_string_view<charT>::npos ? basic_string_view<charT>(str) : basic_string_view<charT>(str, n), 0, n, zero, one)

22.9.2.3 Members [bitset.members]

constexpr bitset& operator&=(const bitset& rhs) noexcept;
Effects: Clears each bit in *this for which the corresponding bit in rhs is clear, and leaves all other bits unchanged.
Returns: *this.
constexpr bitset& operator|=(const bitset& rhs) noexcept;
Effects: Sets each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
Returns: *this.
constexpr bitset& operator^=(const bitset& rhs) noexcept;
Effects: Toggles each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
Returns: *this.
constexpr bitset& operator<<=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
  • If I < pos, the new value is zero;
  • If I >= pos, the new value is the previous value of the bit at position I - pos.
Returns: *this.
constexpr bitset& operator>>=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
  • If pos >= N - I, the new value is zero;
  • If pos < N - I, the new value is the previous value of the bit at position I + pos.
Returns: *this.
constexpr bitset operator<<(size_t pos) const noexcept;
Returns: bitset(*this) <<= pos.
constexpr bitset operator>>(size_t pos) const noexcept;
Returns: bitset(*this) >>= pos.
constexpr bitset& set() noexcept;
Effects: Sets all bits in *this.
Returns: *this.
constexpr bitset& set(size_t pos, bool val = true);
Effects: Stores a new value in the bit at position pos in *this.
If val is true, the stored value is one, otherwise it is zero.
Returns: *this.
Throws: out_of_range if pos does not correspond to a valid bit position.
constexpr bitset& reset() noexcept;
Effects: Resets all bits in *this.
Returns: *this.
constexpr bitset& reset(size_t pos);
Effects: Resets the bit at position pos in *this.
Returns: *this.
Throws: out_of_range if pos does not correspond to a valid bit position.
constexpr bitset operator~() const noexcept;
Effects: Constructs an object x of class bitset and initializes it with *this.
Returns: x.flip().
constexpr bitset& flip() noexcept;
Effects: Toggles all bits in *this.
Returns: *this.
constexpr bitset& flip(size_t pos);
Effects: Toggles the bit at position pos in *this.
Returns: *this.
Throws: out_of_range if pos does not correspond to a valid bit position.
constexpr bool operator[](size_t pos) const;
Preconditions: pos is valid.
Returns: true if the bit at position pos in *this has the value one, otherwise false.
Throws: Nothing.
constexpr bitset::reference operator[](size_t pos);
Preconditions: pos is valid.
Returns: An object of type bitset​::​reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val).
Throws: Nothing.
Remarks: For the purpose of determining the presence of a data race ([intro.multithread]), any access or update through the resulting reference potentially accesses or modifies, respectively, the entire underlying bitset.
constexpr unsigned long to_ulong() const;
Returns: x.
Throws: overflow_error if the integral value x corresponding to the bits in *this cannot be represented as type unsigned long.
constexpr unsigned long long to_ullong() const;
Returns: x.
Throws: overflow_error if the integral value x corresponding to the bits in *this cannot be represented as type unsigned long long.
template<class charT = char, class traits = char_traits<charT>, class Allocator = allocator<charT>> constexpr basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
Effects: Constructs a string object of the appropriate type and initializes it to a string of length N characters.
Each character is determined by the value of its corresponding bit position in *this.
Character position N - 1 corresponds to bit position zero.
Subsequent decreasing character positions correspond to increasing bit positions.
Bit value zero becomes the character zero, bit value one becomes the character one.
Returns: The created object.
constexpr size_t count() const noexcept;
Returns: A count of the number of bits set in *this.
constexpr size_t size() const noexcept;
Returns: N.
constexpr bool operator==(const bitset& rhs) const noexcept;
Returns: true if the value of each bit in *this equals the value of the corresponding bit in rhs.
constexpr bool test(size_t pos) const;
Returns: true if the bit at position pos in *this has the value one.
Throws: out_of_range if pos does not correspond to a valid bit position.
constexpr bool all() const noexcept;
Returns: count() == size().
constexpr bool any() const noexcept;
Returns: count() != 0.
constexpr bool none() const noexcept;
Returns: count() == 0.

22.9.3 bitset hash support [bitset.hash]

template<size_t N> struct hash<bitset<N>>;
The specialization is enabled ([unord.hash]).

22.9.4 bitset operators [bitset.operators]

template<size_t N> constexpr bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) &= rhs.
template<size_t N> constexpr bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) |= rhs.
template<size_t N> constexpr bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) ^= rhs.
template<class charT, class traits, size_t N> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
A formatted input function ([istream.formatted]).
Effects: Extracts up to N characters from is.
Stores these characters in a temporary object str of type basic_string<charT, traits>, then evaluates the expression x = bitset<N>(str).
Characters are extracted and stored until any of the following occurs:
  • N characters have been extracted and stored;
  • end-of-file occurs on the input sequence;
  • the next input character is neither is.widen('0') nor is.widen('1') (in which case the input character is not extracted).
If N > 0 and no characters are stored in str, ios_base​::​failbit is set in the input function's local error state before setstate is called.
Returns: is.
template<class charT, class traits, size_t N> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
Returns: os << x.template to_string<charT, traits, allocator<charT>>( use_facet<ctype<charT>>(os.getloc()).widen('0'), use_facet<ctype<charT>>(os.getloc()).widen('1')) (see [ostream.formatted]).

22.10 Function objects [function.objects]

22.10.1 General [function.objects.general]

A function object type is an object type ([basic.types.general]) that can be the type of the postfix-expression in a function call ([expr.call], [over.match.call]).196
A function object is an object of a function object type.
In the places where one would expect to pass a pointer to a function to an algorithmic template ([algorithms]), the interface is specified to accept a function object.
This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects.
196)196)
Such a type is a function pointer or a class type which has a member operator() or a class type which has a conversion to a pointer to function.

22.10.2 Header <functional> synopsis [functional.syn]

namespace std { // [func.invoke], invoke template<class F, class... Args> constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // freestanding noexcept(is_nothrow_invocable_v<F, Args...>); template<class R, class F, class... Args> constexpr R invoke_r(F&& f, Args&&... args) // freestanding noexcept(is_nothrow_invocable_r_v<R, F, Args...>); // [refwrap], reference_wrapper template<class T> class reference_wrapper; // freestanding template<class T> constexpr reference_wrapper<T> ref(T&) noexcept; // freestanding template<class T> constexpr reference_wrapper<const T> cref(const T&) noexcept; // freestanding template<class T> void ref(const T&&) = delete; // freestanding template<class T> void cref(const T&&) = delete; // freestanding template<class T> constexpr reference_wrapper<T> ref(reference_wrapper<T>) noexcept; // freestanding template<class T> constexpr reference_wrapper<const T> cref(reference_wrapper<T>) noexcept; // freestanding // [refwrap.common.ref], common_reference related specializations template<class R, class T, template<class> class RQual, template<class> class TQual> requires see below struct basic_common_reference<R, T, RQual, TQual>; template<class T, class R, template<class> class TQual, template<class> class RQual> requires see below struct basic_common_reference<T, R, TQual, RQual>; // [arithmetic.operations], arithmetic operations template<class T = void> struct plus; // freestanding template<class T = void> struct minus; // freestanding template<class T = void> struct multiplies; // freestanding template<class T = void> struct divides; // freestanding template<class T = void> struct modulus; // freestanding template<class T = void> struct negate; // freestanding template<> struct plus<void>; // freestanding template<> struct minus<void>; // freestanding template<> struct multiplies<void>; // freestanding template<> struct divides<void>; // freestanding template<> struct modulus<void>; // freestanding template<> struct negate<void>; // freestanding // [comparisons], comparisons template<class T = void> struct equal_to; // freestanding template<class T = void> struct not_equal_to; // freestanding template<class T = void> struct greater; // freestanding template<class T = void> struct less; // freestanding template<class T = void> struct greater_equal; // freestanding template<class T = void> struct less_equal; // freestanding template<> struct equal_to<void>; // freestanding template<> struct not_equal_to<void>; // freestanding template<> struct greater<void>; // freestanding template<> struct less<void>; // freestanding template<> struct greater_equal<void>; // freestanding template<> struct less_equal<void>; // freestanding // [comparisons.three.way], class compare_three_way struct compare_three_way; // freestanding // [logical.operations], logical operations template<class T = void> struct logical_and; // freestanding template<class T = void> struct logical_or; // freestanding template<class T = void> struct logical_not; // freestanding template<> struct logical_and<void>; // freestanding template<> struct logical_or<void>; // freestanding template<> struct logical_not<void>; // freestanding // [bitwise.operations], bitwise operations template<class T = void> struct bit_and; // freestanding template<class T = void> struct bit_or; // freestanding template<class T = void> struct bit_xor; // freestanding template<class T = void> struct bit_not; // freestanding template<> struct bit_and<void>; // freestanding template<> struct bit_or<void>; // freestanding template<> struct bit_xor<void>; // freestanding template<> struct bit_not<void>; // freestanding // [func.identity], identity struct identity; // freestanding // [func.not.fn], function template not_fn template<class F> constexpr unspecified not_fn(F&& f); // freestanding template<auto f> constexpr unspecified not_fn() noexcept; // freestanding // [func.bind.partial], function templates bind_front and bind_back template<class F, class... Args> constexpr unspecified bind_front(F&&, Args&&...); // freestanding template<auto f, class... Args> constexpr unspecified bind_front(Args&&...); // freestanding template<class F, class... Args> constexpr unspecified bind_back(F&&, Args&&...); // freestanding template<auto f, class... Args> constexpr unspecified bind_back(Args&&...); // freestanding // [func.bind], bind template<class T> struct is_bind_expression; // freestanding template<class T> constexpr bool is_bind_expression_v = // freestanding is_bind_expression<T>::value; template<class T> struct is_placeholder; // freestanding template<class T> constexpr int is_placeholder_v = // freestanding is_placeholder<T>::value; template<class F, class... BoundArgs> constexpr unspecified bind(F&&, BoundArgs&&...); // freestanding template<class R, class F, class... BoundArgs> constexpr unspecified bind(F&&, BoundArgs&&...); // freestanding namespace placeholders { // M is the implementation-defined number of placeholders see below _1; // freestanding see below _2; // freestanding . . . see below _M; // freestanding } // [func.memfn], member function adaptors template<class R, class T> constexpr unspecified mem_fn(R T::*) noexcept; // freestanding // [func.wrap], polymorphic function wrappers // [func.wrap.badcall], class bad_function_call class bad_function_call; // [func.wrap.func], class template function template<class> class function; // not defined template<class R, class... ArgTypes> class function<R(ArgTypes...)>; // [func.wrap.func.alg], function specialized algorithms template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept; // [func.wrap.func.nullptr], function null pointer comparison operator functions template<class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // [func.wrap.move], move-only wrapper template<class... S> class move_only_function; // not defined template<class R, class... ArgTypes> class move_only_function<R(ArgTypes...) cv ref noexcept(noex)>; // see below // [func.wrap.copy], copyable wrapper template<class... S> class copyable_function; // not defined template<class R, class... ArgTypes> class copyable_function<R(ArgTypes...) cv ref noexcept(noex)>; // see below // [func.wrap.ref], non-owning wrapper template<class... S> class function_ref; // freestanding, not defined template<class R, class... ArgTypes> class function_ref<R(ArgTypes...) cv noexcept(noex)>; // freestanding, see below // [func.search], searchers template<class ForwardIterator1, class BinaryPredicate = equal_to<>> class default_searcher; // freestanding template<class RandomAccessIterator, class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_searcher; template<class RandomAccessIterator, class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher; // [unord.hash], class template hash template<class T> struct hash; // freestanding namespace ranges { // [range.cmp], concept-constrained comparisons struct equal_to; // freestanding struct not_equal_to; // freestanding struct greater; // freestanding struct less; // freestanding struct greater_equal; // freestanding struct less_equal; // freestanding } template<class Fn, class... Args> concept callable = // exposition only requires (Fn&& fn, Args&&... args) { std::forward<Fn>(fn)(std::forward<Args>(args)...); }; template<class Fn, class... Args> concept nothrow-callable = // exposition only callable<Fn, Args...> && requires (Fn&& fn, Args&&... args) { { std::forward<Fn>(fn)(std::forward<Args>(args)...) } noexcept; }; template<class Fn, class... Args> using call-result-t = decltype(declval<Fn>()(declval<Args>()...)); // exposition only template<const auto& T> using decayed-typeof = decltype(auto(T)); // exposition only }
[Example 1: 
If a C++ program wants to have a by-element addition of two vectors a and b containing double and put the result into a, it can do: transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
— end example]
[Example 2: 
To negate every element of a:
transform(a.begin(), a.end(), a.begin(), negate<double>()); — end example]

22.10.3 Definitions [func.def]

The following definitions apply to this Clause:
A call signature is the name of a return type followed by a parenthesized comma-separated list of zero or more argument types.
A callable type is a function object type ([function.objects]) or a pointer to member.
A callable object is an object of a callable type.
A call wrapper type is a type that holds a callable object and supports a call operation that forwards to that object.
A call wrapper is an object of a call wrapper type.
A target object is the callable object held by a call wrapper.
A call wrapper type may additionally hold a sequence of objects and references that may be passed as arguments to the target object.
These entities are collectively referred to as bound argument entities.
The target object and bound argument entities of the call wrapper are collectively referred to as state entities.

22.10.4 Requirements [func.require]

Define INVOKE(f, t, t, , t) as follows:
  • (t.*f)(t, , t) when f is a pointer to a member function of a class T and is_same_v<T, remove_cvref_t<decltype(t)>> || is_base_of_v<T, remove_cvref_t<decltype(t)>> is true;
  • (t.get().*f)(t, , t) when f is a pointer to a member function of a class T and remove_cvref_t<decltype(t)> is a specialization of reference_wrapper;
  • ((*t).*f)(t, , t) when f is a pointer to a member function of a class T and t does not satisfy the previous two items;
  • t.*f when and f is a pointer to data member of a class T and is_same_v<T, remove_cvref_t<decltype(t)>> || is_base_of_v<T, remove_cvref_t<decltype(t)>> is true;
  • t.get().*f when and f is a pointer to data member of a class T and remove_cvref_t<decltype(t)> is a specialization of reference_wrapper;
  • (*t).*f when and f is a pointer to data member of a class T and t does not satisfy the previous two items;
  • f(t, t, , t) in all other cases.
Define INVOKE<R>(f, t, t, , t) as static_cast<void>(INVOKE(f, t, t, , t)) if R is cv void, otherwise INVOKE(f, t, t, , t) implicitly converted to R.
If reference_converts_from_temporary_v<R, decltype(INVOKE(f, t, t, , t))> is true, INVOKE<R>(f, t, t, , t) is ill-formed.
Every call wrapper ([func.def]) meets the Cpp17MoveConstructible and Cpp17Destructible requirements.
An argument forwarding call wrapper is a call wrapper that can be called with an arbitrary argument list and delivers the arguments to the target object as references.
This forwarding step delivers rvalue arguments as rvalue references and lvalue arguments as lvalue references.
[Note 1: 
In a typical implementation, argument forwarding call wrappers have an overloaded function call operator of the form template<class... UnBoundArgs> constexpr R operator()(UnBoundArgs&&... unbound_args) cv-qual;
— end note]
A perfect forwarding call wrapper is an argument forwarding call wrapper that forwards its state entities to the underlying call expression.
This forwarding step delivers a state entity of type T as cv T& when the call is performed on an lvalue of the call wrapper type and as cv T&& otherwise, where cv represents the cv-qualifiers of the call wrapper and where cv shall be neither volatile nor const volatile.
A call pattern defines the semantics of invoking a perfect forwarding call wrapper.
A postfix call performed on a perfect forwarding call wrapper is expression-equivalent ([defns.expression.equivalent]) to an expression e determined from its call pattern cp by replacing all occurrences of the arguments of the call wrapper and its state entities with references as described in the corresponding forwarding steps.
A simple call wrapper is a perfect forwarding call wrapper that meets the Cpp17CopyConstructible and Cpp17CopyAssignable requirements and whose copy constructor, move constructor, and assignment operators are constexpr functions that do not throw exceptions.
The copy/move constructor of an argument forwarding call wrapper has the same apparent semantics as if memberwise copy/move of its state entities were performed ([class.copy.ctor]).
[Note 2: 
This implies that each of the copy/move constructors has the same exception-specification as the corresponding implicit definition and is declared as constexpr if the corresponding implicit definition would be considered to be constexpr.
— end note]
Argument forwarding call wrappers returned by a given standard library function template have the same type if the types of their corresponding state entities are the same.

22.10.5 invoke functions [func.invoke]

template<class F, class... Args> constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) noexcept(is_nothrow_invocable_v<F, Args...>);
Constraints: is_invocable_v<F, Args...> is true.
Returns: INVOKE(std​::​forward<F>(f), std​::​forward<Args>(args)...) ([func.require]).
template<class R, class F, class... Args> constexpr R invoke_r(F&& f, Args&&... args) noexcept(is_nothrow_invocable_r_v<R, F, Args...>);
Constraints: is_invocable_r_v<R, F, Args...> is true.
Returns: INVOKE<R>(std​::​forward<F>(f), std​::​forward<Args>(args)...) ([func.require]).

22.10.6 Class template reference_wrapper [refwrap]

22.10.6.1 General [refwrap.general]

namespace std { template<class T> class reference_wrapper { public: // types using type = T; // [refwrap.const], constructors template<class U> constexpr reference_wrapper(U&&) noexcept(see below); constexpr reference_wrapper(const reference_wrapper& x) noexcept; // [refwrap.assign], assignment constexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept; // [refwrap.access], access constexpr operator T& () const noexcept; constexpr T& get() const noexcept; // [refwrap.invoke], invocation template<class... ArgTypes> constexpr invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&...) const noexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // [refwrap.comparisons], comparisons friend constexpr bool operator==(reference_wrapper, reference_wrapper); friend constexpr bool operator==(reference_wrapper, const T&); friend constexpr bool operator==(reference_wrapper, reference_wrapper<const T>); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); friend constexpr auto operator<=>(reference_wrapper, const T&); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper<const T>); }; template<class T> reference_wrapper(T&) -> reference_wrapper<T>; }
reference_wrapper<T> is a Cpp17CopyConstructible and Cpp17CopyAssignable wrapper around a reference to an object or function of type T.
reference_wrapper<T> is a trivially copyable type ([basic.types.general]).
The template parameter T of reference_wrapper may be an incomplete type.
[Note 1: 
Using the comparison operators described in [refwrap.comparisons] with T being an incomplete type can lead to an ill-formed program with no diagnostic required ([temp.point], [temp.constr.atomic]).
— end note]

22.10.6.2 Constructors [refwrap.const]

template<class U> constexpr reference_wrapper(U&& u) noexcept(see below);
Let FUN denote the exposition-only functions void FUN(T&) noexcept; void FUN(T&&) = delete;
Constraints: The expression FUN(declval<U>()) is well-formed and is_same_v<remove_cvref_t<U>, reference_wrapper> is false.
Effects: Creates a variable r as if by T& r = std​::​forward<U>(u), then constructs a reference_wrapper object that stores a reference to r.
Remarks: The exception specification is equivalent to noexcept(FUN(declval<U>())).
constexpr reference_wrapper(const reference_wrapper& x) noexcept;
Effects: Constructs a reference_wrapper object that stores a reference to x.get().

22.10.6.3 Assignment [refwrap.assign]

constexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept;
Postconditions: *this stores a reference to x.get().

22.10.6.4 Access [refwrap.access]

constexpr operator T& () const noexcept;
Returns: The stored reference.
constexpr T& get() const noexcept;
Returns: The stored reference.

22.10.6.5 Invocation [refwrap.invoke]

template<class... ArgTypes> constexpr invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&... args) const noexcept(is_nothrow_invocable_v<T&, ArgTypes...>);
Mandates: T is a complete type.
Returns: INVOKE(get(), std​::​forward<ArgTypes>(args)...) ([func.require]).

22.10.6.6 Comparisons [refwrap.comparisons]

friend constexpr bool operator==(reference_wrapper x, reference_wrapper y);
Constraints: The expression x.get() == y.get() is well-formed and its result is convertible to bool.
Returns: x.get() == y.get().
friend constexpr bool operator==(reference_wrapper x, const T& y);
Constraints: The expression x.get() == y is well-formed and its result is convertible to bool.
Returns: x.get() == y.
friend constexpr bool operator==(reference_wrapper x, reference_wrapper<const T> y);
Constraints: is_const_v<T> is false and the expression x.get() == y.get() is well-formed and its result is convertible to bool.
Returns: x.get() == y.get().
friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper y);
Constraints: The expression synth-three-way(x.get(), y.get()) is well-formed.
Returns: synth-three-way(x.get(), y.get()).
friend constexpr auto operator<=>(reference_wrapper x, const T& y);
Constraints: The expression synth-three-way(x.get(), y) is well-formed.
Returns: synth-three-way(x.get(), y).
friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper<const T> y);
Constraints: is_const_v<T> is false.
The expression synth-three-way(x.get(), y.get()) is well-formed.
Returns: synth-three-way(x.get(), y.get()).

22.10.6.7 Helper functions [refwrap.helpers]

The template parameter T of the following ref and cref function templates may be an incomplete type.
template<class T> constexpr reference_wrapper<T> ref(T& t) noexcept;
Returns: reference_wrapper<T>(t).
template<class T> constexpr reference_wrapper<T> ref(reference_wrapper<T> t) noexcept;
Returns: t.
template<class T> constexpr reference_wrapper<const T> cref(const T& t) noexcept;
Returns: reference_wrapper<const T>(t).
template<class T> constexpr reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
Returns: t.

22.10.6.8 common_reference related specializations [refwrap.common.ref]

namespace std { template<class T> constexpr bool is-ref-wrapper = false; // exposition only template<class T> constexpr bool is-ref-wrapper<reference_wrapper<T>> = true; template<class R, class T, class RQ, class TQ> concept ref-wrap-common-reference-exists-with = // exposition only is-ref-wrapper<R> && requires { typename common_reference_t<typename R::type&, TQ>; } && convertible_to<RQ, common_reference_t<typename R::type&, TQ>>; template<class R, class T, template<class> class RQual, template<class> class TQual> requires (ref-wrap-common-reference-exists-with<R, T, RQual<R>, TQual<T>> && !ref-wrap-common-reference-exists-with<T, R, TQual<T>, RQual<R>>) struct basic_common_reference<R, T, RQual, TQual> { using type = common_reference_t<typename R::type&, TQual<T>>; }; template<class T, class R, template<class> class TQual, template<class> class RQual> requires (ref-wrap-common-reference-exists-with<R, T, RQual<R>, TQual<T>> && !ref-wrap-common-reference-exists-with<T, R, TQual<T>, RQual<R>>) struct basic_common_reference<T, R, TQual, RQual> { using type = common_reference_t<typename R::type&, TQual<T>>; }; }

22.10.7 Arithmetic operations [arithmetic.operations]

22.10.7.1 General [arithmetic.operations.general]

The library provides basic function object classes for all of the arithmetic operators in the language ([expr.mul], [expr.add]).

22.10.7.2 Class template plus [arithmetic.operations.plus]

template<class T = void> struct plus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x + y.
template<> struct plus<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u));
Returns: std​::​forward<T>(t) + std​::​forward<U>(u).

22.10.7.3 Class template minus [arithmetic.operations.minus]

template<class T = void> struct minus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x - y.
template<> struct minus<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u));
Returns: std​::​forward<T>(t) - std​::​forward<U>(u).

22.10.7.4 Class template multiplies [arithmetic.operations.multiplies]

template<class T = void> struct multiplies { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x * y.
template<> struct multiplies<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u));
Returns: std​::​forward<T>(t) * std​::​forward<U>(u).

22.10.7.5 Class template divides [arithmetic.operations.divides]

template<class T = void> struct divides { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x / y.
template<> struct divides<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u));
Returns: std​::​forward<T>(t) / std​::​forward<U>(u).

22.10.7.6 Class template modulus [arithmetic.operations.modulus]

template<class T = void> struct modulus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x % y.
template<> struct modulus<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u));
Returns: std​::​forward<T>(t) % std​::​forward<U>(u).

22.10.7.7 Class template negate [arithmetic.operations.negate]

template<class T = void> struct negate { constexpr T operator()(const T& x) const; };
constexpr T operator()(const T& x) const;
Returns: -x.
template<> struct negate<void> { template<class T> constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t)); using is_transparent = unspecified; };
template<class T> constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t));
Returns: -std​::​forward<T>(t).

22.10.8 Comparisons [comparisons]

22.10.8.1 General [comparisons.general]

The library provides basic function object classes for all of the comparison operators in the language ([expr.rel], [expr.eq]).
For templates less, greater, less_equal, and greater_equal, the specializations for any pointer type yield a result consistent with the implementation-defined strict total order over pointers ([defns.order.ptr]).
[Note 1: 
If a < b is well-defined for pointers a and b of type P, then (a < b) == less<P>()(a, b), (a > b) == greater<P>()(a, b), and so forth.
— end note]
For template specializations less<void>, greater<void>, less_equal<void>, and greater_equal<void>, if the call operator calls a built-in operator comparing pointers, the call operator yields a result consistent with the implementation-defined strict total order over pointers.

22.10.8.2 Class template equal_to [comparisons.equal.to]

template<class T = void> struct equal_to { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x == y.
template<> struct equal_to<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u));
Returns: std​::​forward<T>(t) == std​::​forward<U>(u).

22.10.8.3 Class template not_equal_to [comparisons.not.equal.to]

template<class T = void> struct not_equal_to { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x != y.
template<> struct not_equal_to<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u));
Returns: std​::​forward<T>(t) != std​::​forward<U>(u).

22.10.8.4 Class template greater [comparisons.greater]

template<class T = void> struct greater { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x > y.
template<> struct greater<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u));
Returns: std​::​forward<T>(t) > std​::​forward<U>(u).

22.10.8.5 Class template less [comparisons.less]

template<class T = void> struct less { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x < y.
template<> struct less<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u));
Returns: std​::​forward<T>(t) < std​::​forward<U>(u).

22.10.8.6 Class template greater_equal [comparisons.greater.equal]

template<class T = void> struct greater_equal { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x >= y.
template<> struct greater_equal<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u));
Returns: std​::​forward<T>(t) >= std​::​forward<U>(u).

22.10.8.7 Class template less_equal [comparisons.less.equal]

template<class T = void> struct less_equal { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x <= y.
template<> struct less_equal<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u));
Returns: std​::​forward<T>(t) <= std​::​forward<U>(u).

22.10.8.8 Class compare_three_way [comparisons.three.way]

namespace std { struct compare_three_way { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const; using is_transparent = unspecified; }; }
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const;
Constraints: T and U satisfy three_way_comparable_with.
Preconditions: If the expression std​::​forward<T>(t) <=> std​::​forward<U>(u) results in a call to a built-in operator <=> comparing pointers of type P, the conversion sequences from both T and U to P are equality-preserving ([concepts.equality]); otherwise, T and U model three_way_comparable_with.
Effects:
  • If the expression std​::​forward<T>(t) <=> std​::​forward<U>(u) results in a call to a built-in operator <=> comparing pointers of type P, returns strong_ordering​::​less if (the converted value of) t precedes u in the implementation-defined strict total order over pointers ([defns.order.ptr]), strong_ordering​::​greater if u precedes t, and otherwise strong_ordering​::​equal.
  • Otherwise, equivalent to: return std​::​forward<T>(t) <=> std​::​forward<U>(u);

22.10.9 Concept-constrained comparisons [range.cmp]

struct ranges::equal_to { template<class T, class U> constexpr bool operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U> constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy equality_comparable_with.
Preconditions: If the expression std​::​forward<T>(t) == std​::​forward<U>(u) results in a call to a built-in operator == comparing pointers of type P, the conversion sequences from both T and U to P are equality-preserving ([concepts.equality]); otherwise, T and U model equality_comparable_with.
Effects:
  • If the expression std​::​forward<T>(t) == std​::​forward<U>(u) results in a call to a built-in operator == comparing pointers: returns false if either (the converted value of) t precedes u or u precedes t in the implementation-defined strict total order over pointers ([defns.order.ptr]) and otherwise true.
  • Otherwise, equivalent to: return std​::​forward<T>(t) == std​::​forward<U>(u);
struct ranges::not_equal_to { template<class T, class U> constexpr bool operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U> constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy equality_comparable_with.
Effects: Equivalent to: return !ranges::equal_to{}(std::forward<T>(t), std::forward<U>(u));
struct ranges::greater { template<class T, class U> constexpr bool operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U> constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy totally_ordered_with.
Effects: Equivalent to: return ranges::less{}(std::forward<U>(u), std::forward<T>(t));
struct ranges::less { template<class T, class U> constexpr bool operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U> constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy totally_ordered_with.
Preconditions: If the expression std​::​forward<T>(t) < std​::​forward<U>(u) results in a call to a built-in operator < comparing pointers of type P, the conversion sequences from both T and U to P are equality-preserving ([concepts.equality]); otherwise, T and U model totally_ordered_with.
For any expressions ET and EU such that decltype((ET)) is T and decltype((EU)) is U, exactly one of ranges​::​less{}(ET, EU), ranges​::​less{}(EU, ET), or ranges​::​equal_to{}(ET, EU) is true.
Effects:
  • If the expression std​::​forward<T>(t) < std​::​forward<U>(u) results in a call to a built-in operator < comparing pointers: returns true if (the converted value of) t precedes u in the implementation-defined strict total order over pointers ([defns.order.ptr]) and otherwise false.
  • Otherwise, equivalent to: return std​::​forward<T>(t) < std​::​forward<U>(u);
struct ranges::greater_equal { template<class T, class U> constexpr bool operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U> constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy totally_ordered_with.
Effects: Equivalent to: return !ranges::less{}(std::forward<T>(t), std::forward<U>(u));
struct ranges::less_equal { template<class T, class U> constexpr bool operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U> constexpr bool operator()(T&& t, U&& u) const;
Constraints: T and U satisfy totally_ordered_with.
Effects: Equivalent to: return !ranges::less{}(std::forward<U>(u), std::forward<T>(t));

22.10.10 Logical operations [logical.operations]

22.10.10.1 General [logical.operations.general]

The library provides basic function object classes for all of the logical operators in the language ([expr.log.and], [expr.log.or], [expr.unary.op]).

22.10.10.2 Class template logical_and [logical.operations.and]

template<class T = void> struct logical_and { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x && y.
template<> struct logical_and<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u));
Returns: std​::​forward<T>(t) && std​::​forward<U>(u).

22.10.10.3 Class template logical_or [logical.operations.or]

template<class T = void> struct logical_or { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x || y.
template<> struct logical_or<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u));
Returns: std​::​forward<T>(t) || std​::​forward<U>(u).

22.10.10.4 Class template logical_not [logical.operations.not]

template<class T = void> struct logical_not { constexpr bool operator()(const T& x) const; };
constexpr bool operator()(const T& x) const;
Returns: !x.
template<> struct logical_not<void> { template<class T> constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t)); using is_transparent = unspecified; };
template<class T> constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t));
Returns: !std​::​forward<T>(t).

22.10.11 Bitwise operations [bitwise.operations]

22.10.11.1 General [bitwise.operations.general]

The library provides basic function object classes for all of the bitwise operators in the language ([expr.bit.and], [expr.or], [expr.xor], [expr.unary.op]).

22.10.11.2 Class template bit_and [bitwise.operations.and]

template<class T = void> struct bit_and { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x & y.
template<> struct bit_and<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u));
Returns: std​::​forward<T>(t) & std​::​forward<U>(u).

22.10.11.3 Class template bit_or [bitwise.operations.or]

template<class T = void> struct bit_or { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x | y.
template<> struct bit_or<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u));
Returns: std​::​forward<T>(t) | std​::​forward<U>(u).

22.10.11.4 Class template bit_xor [bitwise.operations.xor]

template<class T = void> struct bit_xor { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x ^ y.
template<> struct bit_xor<void> { template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u)); using is_transparent = unspecified; };
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u));
Returns: std​::​forward<T>(t) ^ std​::​forward<U>(u).

22.10.11.5 Class template bit_not [bitwise.operations.not]

template<class T = void> struct bit_not { constexpr T operator()(const T& x) const; };
constexpr T operator()(const T& x) const;
Returns: ~x.
template<> struct bit_not<void> { template<class T> constexpr auto operator()(T&& t) const -> decltype(~std::forward<T>(t)); using is_transparent = unspecified; };
template<class T> constexpr auto operator()(T&& t) const -> decltype(~std::forward<T>(t));
Returns: ~std​::​forward<T>(t).

22.10.12 Class identity [func.identity]

struct identity { template<class T> constexpr T&& operator()(T&& t) const noexcept; using is_transparent = unspecified; }; template<class T> constexpr T&& operator()(T&& t) const noexcept;
Effects: Equivalent to: return std​::​forward<T>(t);

22.10.13 Function template not_fn [func.not.fn]

template<class F> constexpr unspecified not_fn(F&& f);
In the text that follows:
  • g is a value of the result of a not_fn invocation,
  • FD is the type decay_t<F>,
  • fd is the target object of g ([func.def]) of type FD, direct-non-list-initialized with std​::​forward<F​>(f),
  • call_args is an argument pack used in a function call expression ([expr.call]) of g.
Mandates: is_constructible_v<FD, F> && is_move_constructible_v<FD> is true.
Preconditions: FD meets the Cpp17MoveConstructible requirements.
Returns: A perfect forwarding call wrapper ([func.require]) g with call pattern !invoke(fd, call_args...).
Throws: Any exception thrown by the initialization of fd.
template<auto f> constexpr unspecified not_fn() noexcept;
In the text that follows:
  • F is the type of f,
  • g is a value of the result of a not_fn invocation,
  • call_args is an argument pack used in a function call expression ([expr.call]) of g.
Mandates: If is_pointer_v<F> || is_member_pointer_v<F> is true, then f != nullptr is true.
Returns: A perfect forwarding call wrapper ([func.require]) g that does not have state entities, and has the call pattern !invoke(f, call_args...).

22.10.14 Function templates bind_front and bind_back [func.bind.partial]

template<class F, class... Args> constexpr unspecified bind_front(F&& f, Args&&... args); template<class F, class... Args> constexpr unspecified bind_back(F&& f, Args&&... args);
Within this subclause:
  • g is a value of the result of a bind_front or bind_back invocation,
  • FD is the type decay_t<F>,
  • fd is the target object of g ([func.def]) of type FD, direct-non-list-initialized with std​::​forward<F​>(f),
  • BoundArgs is a pack that denotes decay_t<Args>...,
  • bound_args is a pack of bound argument entities of g ([func.def]) of types BoundArgs..., direct-non-list-initialized with std​::​forward<Args>(args)..., respectively, and
  • call_args is an argument pack used in a function call expression ([expr.call]) of g.
Mandates: is_constructible_v<FD, F> && is_move_constructible_v<FD> && (is_constructible_v<BoundArgs, Args> && ...) && (is_move_constructible_v<BoundArgs> && ...) is true.
Preconditions: FD meets the Cpp17MoveConstructible requirements.
For each in BoundArgs, if is an object type, meets the Cpp17MoveConstructible requirements.
Returns: A perfect forwarding call wrapper ([func.require]) g with call pattern:
  • invoke(fd, bound_args..., call_args...) for a bind_front invocation, or
  • invoke(fd, call_args..., bound_args...) for a bind_back invocation.
Throws: Any exception thrown by the initialization of the state entities of g ([func.def]).
template<auto f, class... Args> constexpr unspecified bind_front(Args&&... args); template<auto f, class... Args> constexpr unspecified bind_back(Args&&... args);
Within this subclause:
  • F is the type of f,
  • g is a value of the result of a bind_front or bind_back invocation,
  • BoundArgs is a pack that denotes decay_t<Args>...,
  • bound_args is a pack of bound argument entities of g ([func.def]) of types BoundArgs..., direct-non-list-initialized with std​::​forward<Args>(args)..., respectively, and
  • call_args is an argument pack used in a function call expression ([expr.call]) of g.
Mandates:
  • (is_constructible_v<BoundArgs, Args> && ...) is true, and
  • (is_move_constructible_v<BoundArgs> && ...) is true, and
  • if is_pointer_v<F> || is_member_pointer_v<F> is true, then f != nullptr is true.
Preconditions: For each in BoundArgs, meets the Cpp17MoveConstructible requirements.
Returns: A perfect forwarding call wrapper ([func.require]) g that does not have a target object, and has the call pattern:
  • invoke(f, bound_args..., call_args...) for a bind_front invocation, or
  • invoke(f, call_args..., bound_args...) for a bind_back invocation.
throws Any exception thrown by the initialization of bound_args.

22.10.15 Function object binders [func.bind]

22.10.15.1 General [func.bind.general]

Subclause [func.bind] describes a uniform mechanism for binding arguments of callable objects.

22.10.15.2 Class template is_bind_expression [func.bind.isbind]

namespace std { template<class T> struct is_bind_expression; // see below }
The class template is_bind_expression can be used to detect function objects generated by bind.
The function template bind uses is_bind_expression to detect subexpressions.
Specializations of the is_bind_expression template shall meet the Cpp17UnaryTypeTrait requirements ([meta.rqmts]).
The implementation provides a definition that has a base characteristic of true_type if T is a type returned from bind, otherwise it has a base characteristic of false_type.
A program may specialize this template for a program-defined type T to have a base characteristic of true_type to indicate that T should be treated as a subexpression in a bind call.

22.10.15.3 Class template is_placeholder [func.bind.isplace]

namespace std { template<class T> struct is_placeholder; // see below }
The class template is_placeholder can be used to detect the standard placeholders _1, _2, and so on ([func.bind.place]).
The function template bind uses is_placeholder to detect placeholders.
Specializations of the is_placeholder template shall meet the Cpp17UnaryTypeTrait requirements ([meta.rqmts]).
The implementation provides a definition that has the base characteristic of integral_constant<int, J> if T is the type of std​::​placeholders​::​_J, otherwise it has a base characteristic of integral_constant<int, 0>.
A program may specialize this template for a program-defined type T to have a base characteristic of integral_constant<int, N> with N > 0 to indicate that T should be treated as a placeholder type.

22.10.15.4 Function template bind [func.bind.bind]

In the text that follows:
  • g is a value of the result of a bind invocation,
  • FD is the type decay_t<F>,
  • fd is an lvalue that is a target object of g ([func.def]) of type FD direct-non-list-initialized with std​::​forward<F>(f),
  • is the type in the template parameter pack BoundArgs,
  • is the type decay_t<>,
  • is the argument in the function parameter pack bound_args,
  • is a bound argument entity of g ([func.def]) of type direct-non-list-initialized with std​::​forward<>(),
  • is the deduced type of the UnBoundArgs&&... parameter of the argument forwarding call wrapper, and
  • is the argument associated with .
template<class F, class... BoundArgs> constexpr unspecified bind(F&& f, BoundArgs&&... bound_args); template<class R, class F, class... BoundArgs> constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
Mandates: is_constructible_v<FD, F> is true.
For each in BoundArgs, is_constructible_v<, > is true.
Preconditions: FD and each meet the Cpp17MoveConstructible and Cpp17Destructible requirements.
INVOKE(fd, , , , ) ([func.require]) is a valid expression for some values , , , , where N has the value sizeof...(bound_args).
Returns: An argument forwarding call wrapper g ([func.require]).
A program that attempts to invoke a volatile-qualified g is ill-formed.
When g is not volatile-qualified, invocation of g(, , , ) is expression-equivalent ([defns.expression.equivalent]) to INVOKE(static_cast<>(), static_cast<>(), static_cast<>(), , static_cast<>()) for the first overload, and INVOKE<R>(static_cast<>(), static_cast<>(), static_cast<>(), , static_cast<>()) for the second overload, where the values and types of the target argument and of the bound arguments , , , are determined as specified below.
Throws: Any exception thrown by the initialization of the state entities of g.
[Note 1: 
If all of FD and meet the requirements of Cpp17CopyConstructible, then the return type meets the requirements of Cpp17CopyConstructible.
— end note]
The values of the bound arguments , , , and their corresponding types , , , depend on the types derived from the call to bind and the cv-qualifiers cv of the call wrapper g as follows:
  • if is reference_wrapper<T>, the argument is .get() and its type is T&;
  • if the value of is_bind_expression_v<> is true, the argument is static_cast<cv &>()(std::forward<>()...) and its type is invoke_result_t<cv &, ...>&&;
  • if the value j of is_placeholder_v<> is not zero, the argument is std​::​forward<>() and its type is &&;
  • otherwise, the value is and its type is cv &.
The value of the target argument is fd and its corresponding type is cv FD&.

22.10.15.5 Placeholders [func.bind.place]

namespace std::placeholders { // M is the number of placeholders see below _1; see below _2; . . . see below _M; }
The number M of placeholders is implementation-defined.
All placeholder types meet the Cpp17DefaultConstructible and Cpp17CopyConstructible requirements, and their default constructors and copy/move constructors are constexpr functions that do not throw exceptions.
It is implementation-defined whether placeholder types meet the Cpp17CopyAssignable requirements, but if so, their copy assignment operators are constexpr functions that do not throw exceptions.
Placeholders should be defined as: inline constexpr unspecified _1{};
If they are not, they are declared as: extern unspecified _1;
Placeholders are freestanding items ([freestanding.item]).

22.10.16 Function template mem_fn [func.memfn]

template<class R, class T> constexpr unspecified mem_fn(R T::* pm) noexcept;
Returns: A simple call wrapper ([func.require]) fn with call pattern invoke(pmd, call_args...), where pmd is the target object of fn of type R T​::​* direct-non-list-initialized with pm, and call_args is an argument pack used in a function call expression ([expr.call]) of fn.

22.10.17 Polymorphic function wrappers [func.wrap]

22.10.17.1 General [func.wrap.general]

Subclause [func.wrap] describes polymorphic wrapper classes that encapsulate arbitrary callable objects.
Let t be an object of a type that is a specialization of function, copyable_function, or move_only_function, such that the target object x of t has a type that is a specialization of function, copyable_function, or move_only_function.
Each argument of the invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that has the same type, even if the corresponding parameter is not of reference type.
[Example 1: move_only_function<void(T)> f{copyable_function<void(T)>{[](T) {}}}; T t; f(t); // it is unspecified how many copies of T are made — end example]
Recommended practice: Implementations should avoid double wrapping when constructing polymorphic wrappers from one another.

22.10.17.2 Class bad_function_call [func.wrap.badcall]

An exception of type bad_function_call is thrown by function​::​operator() ([func.wrap.func.inv]) when the function wrapper object has no target.
namespace std { class bad_function_call : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

22.10.17.3 Class template function [func.wrap.func]

22.10.17.3.1 General [func.wrap.func.general]

namespace std { template<class R, class... ArgTypes> class function<R(ArgTypes...)> { public: using result_type = R; // [func.wrap.func.con], construct/copy/destroy function() noexcept; function(nullptr_t) noexcept; function(const function&); function(function&&) noexcept; template<class F> function(F&&); function& operator=(const function&); function& operator=(function&&); function& operator=(nullptr_t) noexcept; template<class F> function& operator=(F&&); template<class F> function& operator=(reference_wrapper<F>) noexcept; ~function(); // [func.wrap.func.mod], function modifiers void swap(function&) noexcept; // [func.wrap.func.cap], function capacity explicit operator bool() const noexcept; // [func.wrap.func.inv], function invocation R operator()(ArgTypes...) const; // [func.wrap.func.targ], function target access const type_info& target_type() const noexcept; template<class T> T* target() noexcept; template<class T> const T* target() const noexcept; }; template<class R, class... ArgTypes> function(R(*)(ArgTypes...)) -> function<R(ArgTypes...)>; template<class F> function(F) -> function<see below>; }
The function class template provides polymorphic wrappers that generalize the notion of a function pointer.
Wrappers can store, copy, and call arbitrary callable objects ([func.def]), given a call signature ([func.def]).
A callable type ([func.def]) F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand ([expr.context]), is well-formed ([func.require]).
The function class template is a call wrapper ([func.def]) whose call signature ([func.def]) is R(ArgTypes...).
[Note 1: 
The types deduced by the deduction guides for function might change in future revisions of C++.
— end note]

22.10.17.3.2 Constructors and destructor [func.wrap.func.con]

function() noexcept;
Postconditions: !*this.
function(nullptr_t) noexcept;
Postconditions: !*this.
function(const function& f);
Postconditions: !*this if !f; otherwise, the target object of *this is a copy of the target object of f.
Throws: Nothing if f's target is a specialization of reference_wrapper or a function pointer.
Otherwise, may throw bad_alloc or any exception thrown by the copy constructor of the stored callable object.
Recommended practice: Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer.
function(function&& f) noexcept;
Postconditions: If !f, *this has no target; otherwise, the target of *this is equivalent to the target of f before the construction, and f is in a valid state with an unspecified value.
Recommended practice: Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer.
template<class F> function(F&& f);
Let FD be decay_t<F>.
Constraints:
  • is_same_v<remove_cvref_t<F>, function> is false, and
  • FD is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Mandates:
  • is_copy_constructible_v<FD> is true, and
  • is_constructible_v<FD, F> is true.
Preconditions: FD meets the Cpp17CopyConstructible requirements.
Postconditions: !*this is true if any of the following hold:
  • f is a null function pointer value.
  • f is a null member pointer value.
  • remove_cvref_t<F> is a specialization of the function class template, and !f is true.
Otherwise, *this has a target object of type FD direct-non-list-initialized with std​::​forward<F>(f).
Throws: Nothing if FD is a specialization of reference_wrapper or a function pointer type.
Otherwise, may throw bad_alloc or any exception thrown by the initialization of the target object.
Recommended practice: Implementations should avoid the use of dynamically allocated memory for small callable objects, for example, where f refers to an object holding only a pointer or reference to an object and a member function pointer.
template<class F> function(F) -> function<see below>;
Constraints: &F​::​operator() is well-formed when treated as an unevaluated operand and either
  • F​::​operator() is a non-static member function and decltype(&F​::​operator()) is either of the form R(G​::​*)(A...) cv & noexcept or of the form R(*)(G, A...) noexcept for a type G, or
  • F​::​operator() is a static member function and decltype(&F​::​operator()) is of the form R(*)(A...) noexcept.
Remarks: The deduced type is function<R(A...)>.
[Example 1: void f() { int i{5}; function g = [&](double) { return i; }; // deduces function<int(double)> } — end example]
function& operator=(const function& f);
Effects: As if by function(f).swap(*this);
Returns: *this.
function& operator=(function&& f);
Effects: Replaces the target of *this with the target of f.
Returns: *this.
function& operator=(nullptr_t) noexcept;
Effects: If *this != nullptr, destroys the target of this.
Postconditions: !(*this).
Returns: *this.
template<class F> function& operator=(F&& f);
Constraints: decay_t<F> is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Effects: As if by: function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
Effects: As if by: function(f).swap(*this);
Returns: *this.
~function();
Effects: If *this != nullptr, destroys the target of this.

22.10.17.3.3 Modifiers [func.wrap.func.mod]

void swap(function& other) noexcept;
Effects: Interchanges the target objects of *this and other.

22.10.17.3.4 Capacity [func.wrap.func.cap]

explicit operator bool() const noexcept;
Returns: true if *this has a target, otherwise false.

22.10.17.3.5 Invocation [func.wrap.func.inv]

R operator()(ArgTypes... args) const;
Returns: INVOKE<R>(f, std​::​forward<ArgTypes>(args)...) ([func.require]), where f is the target object ([func.def]) of *this.
Throws: bad_function_call if !*this; otherwise, any exception thrown by the target object.

22.10.17.3.6 Target access [func.wrap.func.targ]

const type_info& target_type() const noexcept;
Returns: If *this has a target of type T, typeid(T); otherwise, typeid(void).
template<class T> T* target() noexcept; template<class T> const T* target() const noexcept;
Returns: If target_type() == typeid(T) a pointer to the stored function target; otherwise a null pointer.

22.10.17.3.7 Null pointer comparison operator functions [func.wrap.func.nullptr]

template<class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept;
Returns: !f.

22.10.17.3.8 Specialized algorithms [func.wrap.func.alg]

template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
Effects: As if by: f1.swap(f2);

22.10.17.4 Move-only wrapper [func.wrap.move]

22.10.17.4.1 General [func.wrap.move.general]

The header provides partial specializations of move_only_function for each combination of the possible replacements of the placeholders cv, ref, and noex where
  • cv is either const or empty,
  • ref is either &, &&, or empty, and
  • noex is either true or false.
For each of the possible combinations of the placeholders mentioned above, there is a placeholder inv-quals defined as follows:
  • If ref is empty, let inv-quals be cv&,
  • otherwise, let inv-quals be cv ref.

22.10.17.4.2 Class template move_only_function [func.wrap.move.class]

namespace std { template<class R, class... ArgTypes> class move_only_function<R(ArgTypes...) cv ref noexcept(noex)> { public: using result_type = R; // [func.wrap.move.ctor], constructors, assignment, and destructor move_only_function() noexcept; move_only_function(nullptr_t) noexcept; move_only_function(move_only_function&&) noexcept; template<class F> move_only_function(F&&); template<class T, class... Args> explicit move_only_function(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args> explicit move_only_function(in_place_type_t<T>, initializer_list<U>, Args&&...); move_only_function& operator=(move_only_function&&); move_only_function& operator=(nullptr_t) noexcept; template<class F> move_only_function& operator=(F&&); ~move_only_function(); // [func.wrap.move.inv], invocation explicit operator bool() const noexcept; R operator()(ArgTypes...) cv ref noexcept(noex); // [func.wrap.move.util], utility void swap(move_only_function&) noexcept; friend void swap(move_only_function&, move_only_function&) noexcept; friend bool operator==(const move_only_function&, nullptr_t) noexcept; private: template<class VT> static constexpr bool is-callable-from = see below; // exposition only }; }
The move_only_function class template provides polymorphic wrappers that generalize the notion of a callable object ([func.def]).
These wrappers can store, move, and call arbitrary callable objects, given a call signature.
Recommended practice: Implementations should avoid the use of dynamically allocated memory for a small contained value.
[Note 1: 
Such small-object optimization can only be applied to a type T for which is_nothrow_move_constructible_v<T> is true.
— end note]

22.10.17.4.3 Constructors, assignment, and destructor [func.wrap.move.ctor]

template<class VT> static constexpr bool is-callable-from = see below;
If noex is true, is-callable-from<VT> is equal to: is_nothrow_invocable_r_v<R, VT cv ref, ArgTypes...> && is_nothrow_invocable_r_v<R, VT inv-quals, ArgTypes...>
Otherwise, is-callable-from<VT> is equal to: is_invocable_r_v<R, VT cv ref, ArgTypes...> && is_invocable_r_v<R, VT inv-quals, ArgTypes...>
move_only_function() noexcept; move_only_function(nullptr_t) noexcept;
Postconditions: *this has no target object.
move_only_function(move_only_function&& f) noexcept;
Postconditions: The target object of *this is the target object f had before construction, and f is in a valid state with an unspecified value.
template<class F> move_only_function(F&& f);
Let VT be decay_t<F>.
Constraints:
  • remove_cvref_t<F> is not the same type as move_only_function, and
  • remove_cvref_t<F> is not a specialization of in_place_type_t, and
  • is-callable-from<VT> is true.
Mandates: is_constructible_v<VT, F> is true.
Preconditions: VT meets the Cpp17Destructible requirements, and if is_move_constructible_v<VT> is true, VT meets the Cpp17MoveConstructible requirements.
Postconditions: *this has no target object if any of the following hold:
  • f is a null function pointer value, or
  • f is a null member pointer value, or
  • remove_cvref_t<F> is a specialization of the move_only_function class template, and f has no target object.
Otherwise, *this has a target object of type VT direct-non-list-initialized with std​::​forward<F>(f).
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc unless VT is a function pointer or a specialization of reference_wrapper.
template<class T, class... Args> explicit move_only_function(in_place_type_t<T>, Args&&... args);
Let VT be decay_t<T>.
Constraints:
  • is_constructible_v<VT, Args...> is true, and
  • is-callable-from<VT> is true.
Mandates: VT is the same type as T.
Preconditions: VT meets the Cpp17Destructible requirements, and if is_move_constructible_v<VT> is true, VT meets the Cpp17MoveConstructible requirements.
Postconditions: *this has a target object of type VT direct-non-list-initialized with std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc unless VT is a function pointer or a specialization of reference_wrapper.
template<class T, class U, class... Args> explicit move_only_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
Let VT be decay_t<T>.
Constraints:
  • is_constructible_v<VT, initializer_list<U>&, Args...> is true, and
  • is-callable-from<VT> is true.
Mandates: VT is the same type as T.
Preconditions: VT meets the Cpp17Destructible requirements, and if is_move_constructible_v<VT> is true, VT meets the Cpp17MoveConstructible requirements.
Postconditions: *this has a target object of type VT direct-non-list-initialized with ilist, std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc unless VT is a function pointer or a specialization of reference_wrapper.
move_only_function& operator=(move_only_function&& f);
Effects: Equivalent to: move_only_function(std​::​move(f)).swap(*this);
Returns: *this.
move_only_function& operator=(nullptr_t) noexcept;
Effects: Destroys the target object of *this, if any.
Returns: *this.
template<class F> move_only_function& operator=(F&& f);
Effects: Equivalent to: move_only_function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
~move_only_function();
Effects: Destroys the target object of *this, if any.

22.10.17.4.4 Invocation [func.wrap.move.inv]

explicit operator bool() const noexcept;
Returns: true if *this has a target object, otherwise false.
R operator()(ArgTypes... args) cv ref noexcept(noex);
Preconditions: *this has a target object.
Effects: Equivalent to: return INVOKE<R>(static_cast<F inv-quals>(f), std::forward<ArgTypes>(args)...); where f is an lvalue designating the target object of *this and F is the type of f.

22.10.17.4.5 Utility [func.wrap.move.util]

void swap(move_only_function& other) noexcept;
Effects: Exchanges the target objects of *this and other.
friend void swap(move_only_function& f1, move_only_function& f2) noexcept;
Effects: Equivalent to f1.swap(f2).
friend bool operator==(const move_only_function& f, nullptr_t) noexcept;
Returns: true if f has no target object, otherwise false.

22.10.17.5 Copyable wrapper [func.wrap.copy]

22.10.17.5.1 General [func.wrap.copy.general]

The header provides partial specializations of copyable_function for each combination of the possible replacements of the placeholders cv, ref, and noex where
  • cv is either const or empty,
  • ref is either &, &&, or empty, and
  • noex is either true or false.
For each of the possible combinations of the placeholders mentioned above, there is a placeholder inv-quals defined as follows:
  • If ref is empty, let inv-quals be cv&,
  • otherwise, let inv-quals be cv ref.

22.10.17.5.2 Class template copyable_function [func.wrap.copy.class]

namespace std { template<class R, class... ArgTypes> class copyable_function<R(ArgTypes...) cv ref noexcept(noex)> { public: using result_type = R; // [func.wrap.copy.ctor], constructors, assignments, and destructors copyable_function() noexcept; copyable_function(nullptr_t) noexcept; copyable_function(const copyable_function&); copyable_function(copyable_function&&) noexcept; template<class F> copyable_function(F&&); template<class T, class... Args> explicit copyable_function(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args> explicit copyable_function(in_place_type_t<T>, initializer_list<U>, Args&&...); copyable_function& operator=(const copyable_function&); copyable_function& operator=(copyable_function&&); copyable_function& operator=(nullptr_t) noexcept; template<class F> copyable_function& operator=(F&&); ~copyable_function(); // [func.wrap.copy.inv], invocation explicit operator bool() const noexcept; R operator()(ArgTypes...) cv ref noexcept(noex); // [func.wrap.copy.util], utility void swap(copyable_function&) noexcept; friend void swap(copyable_function&, copyable_function&) noexcept; friend bool operator==(const copyable_function&, nullptr_t) noexcept; private: template<class VT> static constexpr bool is-callable-from = see below; // exposition only }; }
The copyable_function class template provides polymorphic wrappers that generalize the notion of a callable object ([func.def]).
These wrappers can store, copy, move, and call arbitrary callable objects, given a call signature.
Recommended practice: Implementations should avoid the use of dynamically allocated memory for a small contained value.
[Note 1: 
Such small-object optimization can only be applied to a type T for which is_nothrow_move_constructible_v<T> is true.
— end note]

22.10.17.5.3 Constructors, assignments, and destructors [func.wrap.copy.ctor]

template<class VT> static constexpr bool is-callable-from = see below;
If noex is true, is-callable-from<VT> is equal to: is_nothrow_invocable_r_v<R, VT cv ref, ArgTypes...> && is_nothrow_invocable_r_v<R, VT inv-quals, ArgTypes...>
Otherwise, is-callable-from<VT> is equal to: is_invocable_r_v<R, VT cv ref, ArgTypes...> && is_invocable_r_v<R, VT inv-quals, ArgTypes...>
copyable_function() noexcept; copyable_function(nullptr_t) noexcept;
Postconditions: *this has no target object.
copyable_function(const copyable_function& f);
Postconditions: *this has no target object if f had no target object.
Otherwise, the target object of *this is a copy of the target object of f.
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc.
copyable_function(copyable_function&& f) noexcept;
Postconditions: The target object of *this is the target object f had before construction, and f is in a valid state with an unspecified value.
template<class F> copyable_function(F&& f);
Let VT be decay_t<F>.
Constraints:
  • remove_cvref_t<F> is not the same type as copyable_function, and
  • remove_cvref_t<F> is not a specialization of in_place_type_t, and
  • is-callable-from<VT> is true.
Mandates:
  • is_constructible_v<VT, F> is true, and
  • is_copy_constructible_v<VT> is true.
Preconditions: VT meets the Cpp17Destructible and Cpp17CopyConstructible requirements.
Postconditions: *this has no target object if any of the following hold:
  • f is a null function pointer value, or
  • f is a null member pointer value, or
  • remove_cvref_t<F> is a specialization of the copyable_function class template, and f has no target object.
Otherwise, *this has a target object of type VT direct-non-list-initialized with std​::​forward<F>(f).
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc unless VT is a function pointer or a specialization of reference_wrapper.
template<class T, class... Args> explicit copyable_function(in_place_type_t<T>, Args&&... args);
Let VT be decay_t<T>.
Constraints:
  • is_constructible_v<VT, Args...> is true, and
  • is-callable-from<VT> is true.
Mandates:
  • VT is the same type as T, and
  • is_copy_constructible_v<VT> is true.
Preconditions: VT meets the Cpp17Destructible and Cpp17CopyConstructible requirements.
Postconditions: *this has a target object of type VT direct-non-list-initialized with std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc unless VT is a pointer or a specialization of reference_wrapper.
template<class T, class U, class... Args> explicit copyable_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
Let VT be decay_t<T>.
Constraints:
  • is_constructible_v<VT, initializer_list<U>&, Args...> is true, and
  • is-callable-from<VT> is true.
Mandates:
  • VT is the same type as T, and
  • is_copy_constructible_v<VT> is true.
Preconditions: VT meets the Cpp17Destructible and Cpp17CopyConstructible requirements.
Postconditions: *this has a target object of type VT direct-non-list-initialized with ilist, std​::​forward<Args>(args)....
Throws: Any exception thrown by the initialization of the target object.
May throw bad_alloc unless VT is a pointer or a specialization of reference_wrapper.
copyable_function& operator=(const copyable_function& f);
Effects: Equivalent to: copyable_function(f).swap(*this);
Returns: *this.
copyable_function& operator=(copyable_function&& f);
Effects: Equivalent to: copyable_function(std​::​move(f)).swap(*this);
Returns: *this.
copyable_function& operator=(nullptr_t) noexcept;
Effects: Destroys the target object of *this, if any.
Returns: *this.
template<class F> copyable_function& operator=(F&& f);
Effects: Equivalent to: copyable_function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
~copyable_function();
Effects: Destroys the target object of *this, if any.

22.10.17.5.4 Invocation [func.wrap.copy.inv]

explicit operator bool() const noexcept;
Returns: true if *this has a target object, otherwise false.
R operator()(ArgTypes... args) cv ref noexcept(noex);
Preconditions: *this has a target object.
Effects: Equivalent to: return INVOKE<R>(static_cast<F inv-quals>(f), std::forward<ArgTypes>(args)...); where f is an lvalue designating the target object of *this and F is the type of f.

22.10.17.5.5 Utility [func.wrap.copy.util]

void swap(copyable_function& other) noexcept;
Effects: Exchanges the target objects of *this and other.
friend void swap(copyable_function& f1, copyable_function& f2) noexcept;
Effects: Equivalent to f1.swap(f2).
friend bool operator==(const copyable_function& f, nullptr_t) noexcept;
Returns: true if f has no target object, otherwise false.

22.10.17.6 Non-owning wrapper [func.wrap.ref]

22.10.17.6.1 General [func.wrap.ref.general]

The header provides partial specializations of function_ref for each combination of the possible replacements of the placeholders cv and noex where:
  • cv is either const or empty, and
  • noex is either true or false.

22.10.17.6.2 Class template function_ref [func.wrap.ref.class]

namespace std { template<class R, class... ArgTypes> class function_ref<R(ArgTypes...) cv noexcept(noex)> { public: // [func.wrap.ref.ctor], constructors and assignment operators template<class F> function_ref(F*) noexcept; template<class F> constexpr function_ref(F&&) noexcept; template<auto f> constexpr function_ref(nontype_t<f>) noexcept; template<auto f, class U> constexpr function_ref(nontype_t<f>, U&&) noexcept; template<auto f, class T> constexpr function_ref(nontype_t<f>, cv T*) noexcept; constexpr function_ref(const function_ref&) noexcept = default; constexpr function_ref& operator=(const function_ref&) noexcept = default; template<class T> function_ref& operator=(T) = delete; // [func.wrap.ref.inv], invocation R operator()(ArgTypes...) const noexcept(noex); private: template<class... T> static constexpr bool is-invocable-using = see below; // exposition only R (*thunk-ptr)(BoundEntityType, Args&&...) noexcept(noex); // exposition only BoundEntityType bound-entity; // exposition only }; // [func.wrap.ref.deduct], deduction guides template<class F> function_ref(F*) -> function_ref<F>; template<auto f> function_ref(nontype_t<f>) -> function_ref<see below>; template<auto f, class T> function_ref(nontype_t<f>, T&&) -> function_ref<see below>; }
An object of class function_ref<R(Args...) cv noexcept(noex)> stores a pointer to function thunk-ptr and an object bound-entity.
bound-entity has an unspecified trivially copyable type BoundEntityType, that models copyable and is capable of storing a pointer to object value or a pointer to function value.
The type of thunk-ptr is R(*)(BoundEntityType, Args&&...) noexcept(noex).
Each specialization of function_ref is a trivially copyable type ([basic.types.general]) that models copyable.
Within [func.wrap.ref], call-args is an argument pack with elements such that decltype((call-args))... denote Args&&... respectively.

22.10.17.6.3 Constructors and assignment operators [func.wrap.ref.ctor]

template<class... T> static constexpr bool is-invocable-using = see below;
If noex is true, is-invocable-using<T...> is equal to: is_nothrow_invocable_r_v<R, T..., ArgTypes...>
Otherwise, is-invocable-using<T...> is equal to: is_invocable_r_v<R, T..., ArgTypes...>
template<class F> function_ref(F* f) noexcept;
Constraints:
  • is_function_v<F> is true, and
  • is-invocable-using<F> is true.
Preconditions: f is not a null pointer.
Effects: Initializes bound-entity with f, and thunk-ptr with the address of a function thunk such that thunk(bound-entity, call-args...) is expression-equivalent ([defns.expression.equivalent]) to invoke_r<R>(f, call-args...).
template<class F> constexpr function_ref(F&& f) noexcept;
Let T be remove_reference_t<F>.
Constraints:
  • remove_cvref_t<F> is not the same type as function_ref,
  • is_member_pointer_v<T> is false, and
  • is-invocable-using<cv T&> is true.
Effects: Initializes bound-entity with addressof(f), and thunk-ptr with the address of a function thunk such that thunk(bound-entity, call-args...) is expression-equivalent ([defns.expression.equivalent]) to invoke_r<R>(static_cast<cv T&>(f), call-args...).
template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
Let F be decltype(f).
Constraints: is-invocable-using<F> is true.
Mandates: If is_pointer_v<F> || is_member_pointer_v<F> is true, then f != nullptr is true.
Effects: Initializes bound-entity with a pointer to an unspecified object or null pointer value, and thunk-ptr with the address of a function thunk such that thunk(bound-entity, call-args...) is expression-equivalent ([defns.expression.equivalent]) to invoke_r<R>(f, call-args...).
template<auto f, class U> constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
Let T be remove_reference_t<U> and F be decltype(f).
Constraints:
  • is_rvalue_reference_v<U&&> is false, and
  • is-invocable-using<F, cv T&> is true.
Mandates: If is_pointer_v<F> || is_member_pointer_v<F> is true, then f != nullptr is true.
Effects: Initializes bound-entity with addressof(obj), and thunk-ptr with the address of a function thunk such that thunk(bound-entity, call-args...) is expression-equivalent ([defns.expression.equivalent]) to invoke_r<R>(f, static_cast<cv T&>(obj), call-args...).
template<auto f, class T> constexpr function_ref(nontype_t<f>, cv T* obj) noexcept;
Let F be decltype(f).
Constraints: is-invocable-using<F, cv T*> is true.
Mandates: If is_pointer_v<F> || is_member_pointer_v<F> is true, then f != nullptr is true.
Preconditions: If is_member_pointer_v<F> is true, obj is not a null pointer.
Effects: Initializes bound-entity with obj, and thunk-ptr with the address of a function thunk such that thunk(bound-entity, call-args...) is expression-equivalent ([defns.expression.equivalent]) to invoke_r<R>(f, obj, call-args...).
template<class T> function_ref& operator=(T) = delete;
Constraints:
  • T is not the same type as function_ref,
  • is_pointer_v<T> is false, and
  • T is not a specialization of nontype_t.

22.10.17.6.4 Invocation [func.wrap.ref.inv]

R operator()(ArgTypes... args) const noexcept(noex);
Effects: Equivalent to: return thunk-ptr(bound-entity, std​::​forward<ArgTypes>(args)...);

22.10.17.6.5 Deduction guides [func.wrap.ref.deduct]

template<class F> function_ref(F*) -> function_ref<F>;
Constraints: is_function_v<F> is true.
template<auto f> function_ref(nontype_t<f>) -> function_ref<see below>;
Let F be remove_pointer_t<decltype(f)>.
Constraints: is_function_v<F> is true.
Remarks: The deduced type is function_ref<F>.
template<auto f, class T> function_ref(nontype_t<f>, T&&) -> function_ref<see below>;
Let F be decltype(f).
Constraints:
  • F is of the form R(G​::​*)(A...) cv & noexcept(E) for a type G, or
  • F is of the form M G​::​* for a type G and an object type M, in which case let R be invoke_result_t<F, T&>, A... be an empty pack, and E be false, or
  • F is of the form R(*)(G, A...) noexcept(E) for a type G.
Remarks: The deduced type is function_ref<R(A...) noexcept(E)>.

22.10.18 Searchers [func.search]

22.10.18.1 General [func.search.general]

Subclause [func.search] provides function object types ([function.objects]) for operations that search for a sequence [pat_first, pat_last) in another sequence [first, last) that is provided to the object's function call operator.
The first sequence (the pattern to be searched for) is provided to the object's constructor, and the second (the sequence to be searched) is provided to the function call operator.
Each specialization of a class template specified in [func.search] shall meet the Cpp17CopyConstructible and Cpp17CopyAssignable requirements.
Template parameters named of templates specified in [func.search] shall meet the same requirements and semantics as specified in [algorithms.general].
Template parameters named Hash shall meet the Cpp17Hash requirements (Table 37).
The Boyer-Moore searcher implements the Boyer-Moore search algorithm.
The Boyer-Moore-Horspool searcher implements the Boyer-Moore-Horspool search algorithm.
In general, the Boyer-Moore searcher will use more memory and give better runtime performance than Boyer-Moore-Horspool.

22.10.18.2 Class template default_searcher [func.search.default]

namespace std { template<class ForwardIterator1, class BinaryPredicate = equal_to<>> class default_searcher { public: constexpr default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last, BinaryPredicate pred = BinaryPredicate()); template<class ForwardIterator2> constexpr pair<ForwardIterator2, ForwardIterator2> operator()(ForwardIterator2 first, ForwardIterator2 last) const; private: ForwardIterator1 pat_first_; // exposition only ForwardIterator1 pat_last_; // exposition only BinaryPredicate pred_; // exposition only }; }
constexpr default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last, BinaryPredicate pred = BinaryPredicate());
Effects: Constructs a default_searcher object, initializing pat_first_ with pat_first, pat_last_ with pat_last, and pred_ with pred.
Throws: Any exception thrown by the copy constructor of BinaryPredicate or ForwardIterator1.
template<class ForwardIterator2> constexpr pair<ForwardIterator2, ForwardIterator2> operator()(ForwardIterator2 first, ForwardIterator2 last) const;
Effects: Returns a pair of iterators i and j such that
  • i == search(first, last, pat_first_, pat_last_, pred_), and
  • if i == last, then j == last, otherwise j == next(i, distance(pat_first_, pat_last_)).

22.10.18.3 Class template boyer_moore_searcher [func.search.bm]

namespace std { template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_searcher { public: boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; // exposition only RandomAccessIterator1 pat_last_; // exposition only Hash hash_; // exposition only BinaryPredicate pred_; // exposition only }; }
boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
Preconditions: The value type of RandomAccessIterator1 meets the Cpp17DefaultConstructible, Cpp17CopyConstructible, and Cpp17CopyAssignable requirements.
Let V be iterator_traits<RandomAccessIterator1>​::​value_type.
For any two values A and B of type V, if pred(A, B) == true, then hf(A) == hf(B) is true.
Effects: Initializes pat_first_ with pat_first, pat_last_ with pat_last, hash_ with hf, and pred_ with pred.
Throws: Any exception thrown by the copy constructor of RandomAccessIterator1, or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1, or the copy constructor or operator() of BinaryPredicate or Hash.
May throw bad_alloc if additional memory needed for internal data structures cannot be allocated.
template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
Mandates: RandomAccessIterator1 and RandomAccessIterator2 have the same value type.
Effects: Finds a subsequence of equal values in a sequence.
Returns: A pair of iterators i and j such that
  • i is the first iterator in the range [first, last - (pat_last_ - pat_first_)) such that for every non-negative integer n less than pat_last_ - pat_first_ the following condition holds: pred(*(i + n), *(pat_first_ + n)) != false, and
  • j == next(i, distance(pat_first_, pat_last_)).
Returns make_pair(first, first) if [pat_first_, pat_last_) is empty, otherwise returns make_pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_last_ - pat_first_) applications of the predicate.

22.10.18.4 Class template boyer_moore_horspool_searcher [func.search.bmh]

namespace std { template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher { public: boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; // exposition only RandomAccessIterator1 pat_last_; // exposition only Hash hash_; // exposition only BinaryPredicate pred_; // exposition only }; }
boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
Preconditions: The value type of RandomAccessIterator1 meets the Cpp17DefaultConstructible, Cpp17CopyConstructible, and Cpp17CopyAssignable requirements.
Let V be iterator_traits<RandomAccessIterator1>​::​value_type.
For any two values A and B of type V, if pred(A, B) == true, then hf(A) == hf(B) is true.
Effects: Initializes pat_first_ with pat_first, pat_last_ with pat_last, hash_ with hf, and pred_ with pred.
Throws: Any exception thrown by the copy constructor of RandomAccessIterator1, or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1, or the copy constructor or operator() of BinaryPredicate or Hash.
May throw bad_alloc if additional memory needed for internal data structures cannot be allocated.
template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
Mandates: RandomAccessIterator1 and RandomAccessIterator2 have the same value type.
Effects: Finds a subsequence of equal values in a sequence.
Returns: A pair of iterators i and j such that
  • i is the first iterator in the range [first, last - (pat_last_ - pat_first_)) such that for every non-negative integer n less than pat_last_ - pat_first_ the following condition holds: pred(*(i + n), *(pat_first_ + n)) != false, and
  • j == next(i, distance(pat_first_, pat_last_)).
Returns make_pair(first, first) if [pat_first_, pat_last_) is empty, otherwise returns make_pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_last_ - pat_first_) applications of the predicate.

22.10.19 Class template hash [unord.hash]

The unordered associative containers defined in [unord] use specializations of the class template hash ([functional.syn]) as the default hash function.
Each specialization of hash is either enabled or disabled, as described below.
[Note 1: 
Enabled specializations meet the Cpp17Hash requirements, and disabled specializations do not.
— end note]
Each header that declares the template hash provides enabled specializations of hash for nullptr_t and all cv-unqualified arithmetic, enumeration, and pointer types.
For any type Key for which neither the library nor the user provides an explicit or partial specialization of the class template hash, hash<Key> is disabled.
If the library provides an explicit or partial specialization of hash<Key>, that specialization is enabled except as noted otherwise, and its member functions are noexcept except as noted otherwise.
If H is a disabled specialization of hash, these values are false: is_default_constructible_v<H>, is_copy_constructible_v<H>, is_move_constructible_v<H>, is_copy_assignable_v<H>, and is_move_assignable_v<H>.
Disabled specializations of hash are not function object types ([function.objects]).
[Note 2: 
This means that the specialization of hash exists, but any attempts to use it as a Cpp17Hash will be ill-formed.
— end note]
An enabled specialization hash<Key> will:
  • meet the Cpp17Hash requirements (Table 37), with Key as the function call argument type, the Cpp17DefaultConstructible requirements (Table 30), the Cpp17CopyAssignable requirements (Table 34), the Cpp17Swappable requirements ([swappable.requirements]),
  • meet the requirement that if k1 == k2 is true, h(k1) == h(k2) is also true, where h is an object of type hash<Key> and k1 and k2 are objects of type Key;
  • meet the requirement that the expression h(k), where h is an object of type hash<Key> and k is an object of type Key, shall not throw an exception unless hash<Key> is a program-defined specialization.

22.11 Bit manipulation [bit]

22.11.1 General [bit.general]

The header <bit> provides components to access, manipulate and process both individual bits and bit sequences.

22.11.2 Header <bit> synopsis [bit.syn]

// all freestanding namespace std { // [bit.cast], bit_cast template<class To, class From> constexpr To bit_cast(const From& from) noexcept; // [bit.byteswap], byteswap template<class T> constexpr T byteswap(T value) noexcept; // [bit.pow.two], integral powers of 2 template<class T> constexpr bool has_single_bit(T x) noexcept; template<class T> constexpr T bit_ceil(T x); template<class T> constexpr T bit_floor(T x) noexcept; template<class T> constexpr int bit_width(T x) noexcept; // [bit.rotate], rotating template<class T> constexpr T rotl(T x, int s) noexcept; template<class T> constexpr T rotr(T x, int s) noexcept; // [bit.count], counting template<class T> constexpr int countl_zero(T x) noexcept; template<class T> constexpr int countl_one(T x) noexcept; template<class T> constexpr int countr_zero(T x) noexcept; template<class T> constexpr int countr_one(T x) noexcept; template<class T> constexpr int popcount(T x) noexcept; // [bit.endian], endian enum class endian { little = see below, big = see below, native = see below }; }

22.11.3 Function template bit_cast [bit.cast]

template<class To, class From> constexpr To bit_cast(const From& from) noexcept;
Constraints:
  • sizeof(To) == sizeof(From) is true;
  • is_trivially_copyable_v<To> is true; and
  • is_trivially_copyable_v<From> is true.
Returns: An object of type To.
Implicitly creates objects nested within the result ([intro.object]).
Each bit of the value representation of the result is equal to the corresponding bit in the object representation of from.
Padding bits of the result are unspecified.
For the result and each object created within it, if there is no value of the object's type corresponding to the value representation produced, the behavior is undefined.
If there are multiple such values, which value is produced is unspecified.
A bit in the value representation of the result is indeterminate if it does not correspond to a bit in the value representation of from or corresponds to a bit for which the smallest enclosing object is not within its lifetime or has an indeterminate value ([basic.indet]).
A bit in the value representation of the result is erroneous if it corresponds to a bit for which the smallest enclosing object has an erroneous value.
For each bit b in the value representation of the result that is indeterminate or erroneous, let u be the smallest object containing that bit enclosing b:
  • If u is of unsigned ordinary character type or std​::​byte type, u has an indeterminate value if any of the bits in its value representation are indeterminate, or otherwise has an erroneous value.
  • Otherwise, if b is indeterminate, the behavior is undefined.
  • Otherwise, the behavior is erroneous, and the result is as specified above.
The result does not otherwise contain any indeterminate or erroneous values.
Remarks: This function is constexpr if and only if To, From, and the types of all subobjects of To and From are types T such that:
  • is_union_v<T> is false;
  • is_pointer_v<T> is false;
  • is_member_pointer_v<T> is false;
  • is_volatile_v<T> is false; and
  • T has no non-static data members of reference type.

22.11.4 byteswap [bit.byteswap]

template<class T> constexpr T byteswap(T value) noexcept;
Constraints: T models integral.
Mandates: T does not have padding bits ([basic.types.general]).
Let the sequence R comprise the bytes of the object representation of value in reverse order.
Returns: An object v of type T such that each byte in the object representation of v is equal to the byte in the corresponding position in R.

22.11.5 Integral powers of 2 [bit.pow.two]

template<class T> constexpr bool has_single_bit(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: true if x is an integral power of two; false otherwise.
template<class T> constexpr T bit_ceil(T x);
Let N be the smallest power of 2 greater than or equal to x.
Constraints: T is an unsigned integer type ([basic.fundamental]).
Preconditions: N is representable as a value of type T.
Returns: N.
Throws: Nothing.
Remarks: A function call expression that violates the precondition in the Preconditions: element is not a core constant expression ([expr.const]).
template<class T> constexpr T bit_floor(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: If x == 0, 0; otherwise the maximal value y such that has_single_bit(y) is true and y <= x.
template<class T> constexpr int bit_width(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any fractional part discarded.

22.11.6 Rotating [bit.rotate]

In the following descriptions, let N denote numeric_limits<T>​::​digits.
template<class T> constexpr T rotl(T x, int s) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Let r be s % N.
Returns: If r is 0, x; if r is positive, (x << r) | (x >> (N - r)); if r is negative, rotr(x, -r).
template<class T> constexpr T rotr(T x, int s) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Let r be s % N.
Returns: If r is 0, x; if r is positive, (x >> r) | (x << (N - r)); if r is negative, rotl(x, -r).

22.11.7 Counting [bit.count]

In the following descriptions, let N denote numeric_limits<T>​::​digits.
template<class T> constexpr int countl_zero(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 0 bits in the value of x, starting from the most significant bit.
[Note 1: 
Returns N if x == 0.
— end note]
template<class T> constexpr int countl_one(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 1 bits in the value of x, starting from the most significant bit.
[Note 2: 
Returns N if x == numeric_limits<T>​::​max().
— end note]
template<class T> constexpr int countr_zero(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 0 bits in the value of x, starting from the least significant bit.
[Note 3: 
Returns N if x == 0.
— end note]
template<class T> constexpr int countr_one(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 1 bits in the value of x, starting from the least significant bit.
[Note 4: 
Returns N if x == numeric_limits<T>​::​max().
— end note]
template<class T> constexpr int popcount(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of 1 bits in the value of x.

22.11.8 Endian [bit.endian]

Two common methods of byte ordering in multibyte scalar types are big-endian and little-endian in the execution environment.
Big-endian is a format for storage of binary data in which the most significant byte is placed first, with the rest in descending order.
Little-endian is a format for storage of binary data in which the least significant byte is placed first, with the rest in ascending order.
This subclause describes the endianness of the scalar types of the execution environment.
enum class endian { little = see below, big = see below, native = see below };
If all scalar types have size 1 byte, then all of endian​::​little, endian​::​big, and endian​::​native have the same value.
Otherwise, endian​::​little is not equal to endian​::​big.
If all scalar types are big-endian, endian​::​native is equal to endian​::​big.
If all scalar types are little-endian, endian​::​native is equal to endian​::​little.
Otherwise, endian​::​native is not equal to either endian​::​big or endian​::​little.

22.12 Header <stdbit.h> synopsis [stdbit.h.syn]

#define __STDC_VERSION_STDBIT_H__ 202311L #define __STDC_ENDIAN_BIG__ see below #define __STDC_ENDIAN_LITTLE__ see below #define __STDC_ENDIAN_NATIVE__ see below unsigned int stdc_leading_zeros_uc(unsigned char value); unsigned int stdc_leading_zeros_us(unsigned short value); unsigned int stdc_leading_zeros_ui(unsigned int value); unsigned int stdc_leading_zeros_ul(unsigned long int value); unsigned int stdc_leading_zeros_ull(unsigned long long int value); template<class T> see below stdc_leading_zeros(T value); unsigned int stdc_leading_ones_uc(unsigned char value); unsigned int stdc_leading_ones_us(unsigned short value); unsigned int stdc_leading_ones_ui(unsigned int value); unsigned int stdc_leading_ones_ul(unsigned long int value); unsigned int stdc_leading_ones_ull(unsigned long long int value); template<class T> see below stdc_leading_ones(T value); unsigned int stdc_trailing_zeros_uc(unsigned char value); unsigned int stdc_trailing_zeros_us(unsigned short value); unsigned int stdc_trailing_zeros_ui(unsigned int value); unsigned int stdc_trailing_zeros_ul(unsigned long int value); unsigned int stdc_trailing_zeros_ull(unsigned long long int value); template<class T> see below stdc_trailing_zeros(T value); unsigned int stdc_trailing_ones_uc(unsigned char value); unsigned int stdc_trailing_ones_us(unsigned short value); unsigned int stdc_trailing_ones_ui(unsigned int value); unsigned int stdc_trailing_ones_ul(unsigned long int value); unsigned int stdc_trailing_ones_ull(unsigned long long int value); template<class T> see below stdc_trailing_ones(T value); unsigned int stdc_first_leading_zero_uc(unsigned char value); unsigned int stdc_first_leading_zero_us(unsigned short value); unsigned int stdc_first_leading_zero_ui(unsigned int value); unsigned int stdc_first_leading_zero_ul(unsigned long int value); unsigned int stdc_first_leading_zero_ull(unsigned long long int value); template<class T> see below stdc_first_leading_zero(T value); unsigned int stdc_first_leading_one_uc(unsigned char value); unsigned int stdc_first_leading_one_us(unsigned short value); unsigned int stdc_first_leading_one_ui(unsigned int value); unsigned int stdc_first_leading_one_ul(unsigned long int value); unsigned int stdc_first_leading_one_ull(unsigned long long int value); template<class T> see below stdc_first_leading_one(T value); unsigned int stdc_first_trailing_zero_uc(unsigned char value); unsigned int stdc_first_trailing_zero_us(unsigned short value); unsigned int stdc_first_trailing_zero_ui(unsigned int value); unsigned int stdc_first_trailing_zero_ul(unsigned long int value); unsigned int stdc_first_trailing_zero_ull(unsigned long long int value); template<class T> see below stdc_first_trailing_zero(T value); unsigned int stdc_first_trailing_one_uc(unsigned char value); unsigned int stdc_first_trailing_one_us(unsigned short value); unsigned int stdc_first_trailing_one_ui(unsigned int value); unsigned int stdc_first_trailing_one_ul(unsigned long int value); unsigned int stdc_first_trailing_one_ull(unsigned long long int value); template<class T> see below stdc_first_trailing_one(T value); unsigned int stdc_count_zeros_uc(unsigned char value); unsigned int stdc_count_zeros_us(unsigned short value); unsigned int stdc_count_zeros_ui(unsigned int value); unsigned int stdc_count_zeros_ul(unsigned long int value); unsigned int stdc_count_zeros_ull(unsigned long long int value); template<class T> see below stdc_count_zeros(T value); unsigned int stdc_count_ones_uc(unsigned char value); unsigned int stdc_count_ones_us(unsigned short value); unsigned int stdc_count_ones_ui(unsigned int value); unsigned int stdc_count_ones_ul(unsigned long int value); unsigned int stdc_count_ones_ull(unsigned long long int value); template<class T> see below stdc_count_ones(T value); bool stdc_has_single_bit_uc(unsigned char value); bool stdc_has_single_bit_us(unsigned short value); bool stdc_has_single_bit_ui(unsigned int value); bool stdc_has_single_bit_ul(unsigned long int value); bool stdc_has_single_bit_ull(unsigned long long int value); template<class T> bool stdc_has_single_bit(T value); unsigned int stdc_bit_width_uc(unsigned char value); unsigned int stdc_bit_width_us(unsigned short value); unsigned int stdc_bit_width_ui(unsigned int value); unsigned int stdc_bit_width_ul(unsigned long int value); unsigned int stdc_bit_width_ull(unsigned long long int value); template<class T> see below stdc_bit_width(T value); unsigned char stdc_bit_floor_uc(unsigned char value); unsigned short stdc_bit_floor_us(unsigned short value); unsigned int stdc_bit_floor_ui(unsigned int value); unsigned long int stdc_bit_floor_ul(unsigned long int value); unsigned long long int stdc_bit_floor_ull(unsigned long long int value); template<class T> T stdc_bit_floor(T value); unsigned char stdc_bit_ceil_uc(unsigned char value); unsigned short stdc_bit_ceil_us(unsigned short value); unsigned int stdc_bit_ceil_ui(unsigned int value); unsigned long int stdc_bit_ceil_ul(unsigned long int value); unsigned long long int stdc_bit_ceil_ull(unsigned long long int value); template<class T> T stdc_bit_ceil(T value);
For a function template whose return type is not specified above, the return type is an implementation-defined unsigned integer type large enough to represent all possible result values.
Each function template has the same semantics as the corresponding type-generic function with the same name specified in ISO/IEC 9899:2024, 7.18.
Mandates: T is an unsigned integer type.
Otherwise, the contents and meaning of the header <stdbit.h> are the same as the C standard library header <stdbit.h>.
See also: ISO/IEC 9899:2024, 7.18