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 34.
Subclause | Header(s) | |
[utility] | Utility components | <utility> |
[intseq] | Compile-time integer sequences | <utility> |
[pairs] | Pairs | <utility> |
[tuple] | Tuples | <tuple> |
[optional] | Optional objects | <optional> |
[variant] | Variants | <variant> |
[any] | Storage for any type | <any> |
[bitset] | Fixed-size sequences of bits | <bitset> |
[memory] | Memory | <memory> |
<cstdlib> | ||
[smartptr] | Smart pointers | <memory> |
[mem.res] | Memory resources | <memory_resource> |
[allocator.adaptor] | Scoped allocators | <scoped_allocator> |
[function.objects] | Function objects | <functional> |
[meta] | Type traits | <type_traits> |
[ratio] | Compile-time rational arithmetic | <ratio> |
[time] | Time utilities | <chrono> |
<ctime> | ||
[type.index] | Type indexes | <typeindex> |
[execpol] | Execution policies | <execution> |
This subclause contains some basic function and class templates that are used throughout the rest of the library.
#include <initializer_list> // see [initializer_list.syn] namespace std { // [operators], operators namespace rel_ops { template<class T> bool operator!=(const T&, const T&); template<class T> bool operator> (const T&, const T&); template<class T> bool operator<=(const T&, const T&); template<class T> bool operator>=(const T&, const T&); } // [utility.swap], swap template <class T> void swap(T& a, T& b) noexcept(see below); template <class T, size_t N> void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>); // [utility.exchange], exchange template <class T, class U = T> T exchange(T& obj, U&& new_val); // [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> 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 // [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; // [pairs.spec], pair specialized algorithms template <class T1, class T2> constexpr bool operator==(const pair<T1, T2>&, const pair<T1, T2>&); template <class T1, class T2> constexpr bool operator< (const pair<T1, T2>&, const pair<T1, T2>&); template <class T1, class T2> constexpr bool operator!=(const pair<T1, T2>&, const pair<T1, T2>&); template <class T1, class T2> constexpr bool operator> (const pair<T1, T2>&, const pair<T1, T2>&); template <class T1, class T2> constexpr bool operator>=(const pair<T1, T2>&, const pair<T1, T2>&); template <class T1, class T2> constexpr bool operator<=(const pair<T1, T2>&, const pair<T1, T2>&); template <class T1, class T2> void swap(pair<T1, T2>& x, 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> class tuple_size; template <size_t I, class T> class tuple_element; template <class T1, class T2> struct tuple_size<pair<T1, T2>>; template <class T1, class T2> struct tuple_element<0, pair<T1, T2>>; template <class T1, class T2> struct tuple_element<1, 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> inline 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> inline constexpr in_place_index_t<I> in_place_index{}; // floating-point format for primitive numerical conversion enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific }; // [utility.to.chars], primitive numerical output conversion struct to_chars_result { char* ptr; error_code ec; }; to_chars_result to_chars(char* first, char* last, see below value, int base = 10); to_chars_result to_chars(char* first, char* last, float value); to_chars_result to_chars(char* first, char* last, double value); to_chars_result to_chars(char* first, char* last, long double value); to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); to_chars_result to_chars(char* first, char* last, float value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt, int precision); // [utility.from.chars], primitive numerical input conversion struct from_chars_result { const char* ptr; error_code ec; }; from_chars_result from_chars(const char* first, const char* last, see below& value, int base = 10); from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, long double& value, chars_format fmt = chars_format::general); }
The header <utility> defines several types and function templates that are described in this Clause. It also defines the template pair and various function templates that operate on pair objects.
To avoid redundant definitions of operator!= out of operator== and operators >, <=, and >= out of operator<, the library provides the following:
template <class T> bool operator!=(const T& x, const T& y);
Requires: Type T is EqualityComparable.
template <class T> bool operator>(const T& x, const T& y);
Requires: Type T is LessThanComparable.
template <class T> bool operator<=(const T& x, const T& y);
Requires: Type T is LessThanComparable.
template <class T> bool operator>=(const T& x, const T& y);
Requires: Type T is LessThanComparable.
template <class T>
void swap(T& a, T& b) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_move_constructible_v<T> is true and is_move_assignable_v<T> is true. The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
Requires: Type T shall be MoveConstructible and MoveAssignable.
template <class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
Remarks: This function shall not participate in overload resolution unless is_swappable_v<T> is true.
Requires: a[i] shall be swappable with b[i] for all i in the range [0, N).
template <class T, class U = T> T exchange(T& obj, U&& new_val);
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 ([csignal.syn]).
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
Remarks: If the second form is instantiated with an lvalue reference type, the program is ill-formed.
[ Example:
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> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
[ Example:
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> sp1 = 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;
template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
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
[ Example:
template <class To, class From> decltype(static_cast<To>(declval<From>())) convert(From&&);
declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To. For another example see class template common_type ([meta.trans.other]). — end example ]
All functions named to_chars convert value into a character string by successively filling the range [first, last), where [first, last) is required to be a valid range. If the member ec of the return value is such that the value, when converted to bool, is false, the conversion was successful and the member ptr is the one-past-the-end pointer of the characters written. Otherwise, the member ec has the value errc::value_too_large, the member ptr has the value last, and the contents of the range [first, last) are unspecified.
The functions that take a floating-point value but not a precision parameter ensure that the string representation consists of the smallest number of characters such that there is at least one digit before the radix point (if present) and parsing the representation using the corresponding from_chars function recovers value exactly. [ Note: This guarantee applies only if to_chars and from_chars are executed on the same implementation. — end note ]
The functions taking a chars_format parameter determine the conversion specifier for printf as follows: The conversion specifier is f if fmt is chars_format::fixed, e if fmt is chars_format::scientific, a (without leading "0x" in the result) if fmt is chars_format::hex, and g if fmt is chars_format::general.
to_chars_result to_chars(char* first, char* last, see below value, int base = 10);
Effects: The value of value is converted to a string of digits in the given base (with no redundant leading zeroes). Digits in the range 10..35 (inclusive) are represented as lowercase characters a..z. If value is less than zero, the representation starts with a minus sign.
Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the type of the parameter value.
to_chars_result to_chars(char* first, char* last, float value);
to_chars_result to_chars(char* first, char* last, double value);
to_chars_result to_chars(char* first, char* last, long double value);
Effects: value is converted to a string in the style of printf in the "C" locale. The conversion specifier is f or e, chosen according to the requirement for a shortest representation (see above); a tie is resolved in favor of f.
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt);
to_chars_result to_chars(char* first, char* last, double value, chars_format fmt);
to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt);
to_chars_result to_chars(char* first, char* last, float value,
chars_format fmt, int precision);
to_chars_result to_chars(char* first, char* last, double value,
chars_format fmt, int precision);
to_chars_result to_chars(char* first, char* last, long double value,
chars_format fmt, int precision);
Effects: value is converted to a string in the style of printf in the "C" locale with the given precision.
See also: ISO C 7.21.6.1.
All functions named from_chars analyze the string [first, last) for a pattern, where [first, last) is required to be a valid range. If no characters match the pattern, value is unmodified, the member ptr of the return value is first and the member ec is equal to errc::invalid_argument. Otherwise, the characters matching the pattern are interpreted as a representation of a value of the type of value. The member ptr of the return value points to the first character not matching the pattern, or has the value last if all characters match. If the parsed value is not in the range representable by the type of value, value is unmodified and the member ec of the return value is equal to errc::result_out_of_range. Otherwise, value is set to the parsed value and the member ec is set such that the conversion to bool yields false.
from_chars_result from_chars(const char* first, const char* last,
see below& value, int base = 10);
Effects: The pattern is the expected form of the subject sequence in the "C" locale for the given nonzero base, as described for strtol, except that no "0x" or "0X" prefix shall appear if the value of base is 16, and except that a minus sign is the only sign that may appear, and only if value has a signed type.
Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the referenced type of the parameter value.
from_chars_result from_chars(const char* first, const char* last, float& value,
chars_format fmt = chars_format::general);
from_chars_result from_chars(const char* first, const char* last, double& value,
chars_format fmt = chars_format::general);
from_chars_result from_chars(const char* first, const char* last, long double& value,
chars_format fmt = chars_format::general);
Effects: The pattern is the expected form of the subject sequence in the "C" locale, as described for strtod, except that
the only sign that may appear is a minus sign;
if fmt has chars_format::scientific set but not chars_format::fixed, the otherwise optional exponent part shall appear;
if fmt has chars_format::fixed set but not chars_format::scientific, the optional exponent part shall not appear; and
if fmt is chars_format::hex, the prefix "0x" or "0X" is assumed. [ Example: The string 0x123 is parsed to have the value 0 with remaining characters x123. — end example ]
In any case, the resulting value is one of at most two floating-point values closest to the value of the string matching the pattern.
See also: ISO C 7.22.1.3, ISO C 7.22.1.4.
The library provides a class template that can represent an integer sequence. When used as an argument to a function template the parameter pack defining the sequence can be deduced and used in a pack expansion. [ Note: The index_sequence alias template is provided for the common case of an integer sequence of type size_t; see also [tuple.apply]. — end note ]
namespace std { template<class T, T... I> struct integer_sequence { using value_type = T; static constexpr size_t size() noexcept { return sizeof...(I); } }; }
template<class T, T N>
using make_integer_sequence = integer_sequence<T, see below>;
If N is negative the program is ill-formed. The alias template make_integer_sequence denotes a specialization of integer_sequence with N template non-type arguments. The type make_integer_sequence<T, N> denotes the type integer_sequence<T, 0, 1, ..., N-1>. [ Note: make_integer_sequence<int, 0> denotes the type integer_sequence<int> — end note ]
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]).
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; EXPLICIT constexpr pair(); EXPLICIT constexpr pair(const T1& x, const T2& y); template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y); template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p); template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p); template <class... Args1, class... Args2> pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args); pair& operator=(const pair& p); template<class U1, class U2> pair& operator=(const pair<U1, U2>& p); pair& operator=(pair&& p) noexcept(see below); template<class U1, class U2> pair& operator=(pair<U1, U2>&& p); void swap(pair& p) noexcept(see below); }; template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>; }
Constructors and member functions of pair shall 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 shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function. The destructor of pair shall be a trivial destructor if (is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>) is true.
EXPLICIT constexpr pair();
Remarks: This constructor shall not participate in overload resolution unless is_default_constructible_v<first_type> is true and is_default_constructible_v<second_type> is true. [ Note: This behavior can be implemented by a constructor template with default template arguments. — end note ] The constructor is explicit if and only if either first_type or second_type is not implicitly default-constructible. [ Note: This behavior can be implemented with a trait that checks whether a const first_type& or a const second_type& can be initialized with {}. — end note ]
EXPLICIT constexpr pair(const T1& x, const T2& y);
Remarks: This constructor shall not participate in overload resolution unless is_copy_constructible_v<first_type> is true and is_copy_constructible_v<second_type> is true. The constructor is explicit if and only if is_convertible_v<const first_type&, first_type> is false or is_convertible_v<const second_type&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<first_type, U1&&> is true and is_constructible_v<second_type, U2&&> is true. The constructor is explicit if and only if is_convertible_v<U1&&, first_type> is false or is_convertible_v<U2&&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<first_type, const U1&> is true and is_constructible_v<second_type, const U2&> is true. The constructor is explicit if and only if is_convertible_v<const U1&, first_type> is false or is_convertible_v<const U2&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
Effects: Initializes first with std::forward<U1>(p.first) and second with std::forward<U2>(p.second).
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<first_type, U1&&> is true and is_constructible_v<second_type, U2&&> is true. The constructor is explicit if and only if is_convertible_v<U1&&, first_type> is false or is_convertible_v<U2&&, second_type> is false.
template<class... Args1, class... Args2>
pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
Requires: is_constructible_v<first_type, Args1&&...> is true and is_constructible_v<second_type, 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.
pair& operator=(const pair& p);
Remarks: This operator shall be defined as deleted unless is_copy_assignable_v<first_type> is true and is_copy_assignable_v<second_type> is true.
template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<first_type&, const U1&> is true and is_assignable_v<second_type&, const U2&> is true.
pair& operator=(pair&& p) noexcept(see below);
Effects:
Assigns to first with std::forward<first_type>(p.first)
and to second with
std::forward<second_type>(p.second).
Remarks: This operator shall be defined as deleted unless is_move_assignable_v<first_type> is true and is_move_assignable_v<second_type> is true.
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
Effects:
Assigns to first with std::forward<U>(p.first)
and to second with
std::forward<V>(p.second).
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<first_type&, U1&&> is true and is_assignable_v<second_type&, U2&&> is true.
void swap(pair& p) noexcept(see below);
Requires: first shall be swappable with p.first and second shall be swappable with p.second.
template <class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless is_swappable_v<T1> is true and is_swappable_v<T2> is true.
template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y)), where V1 and V2 are determined as follows: Let Ui be decay_t<Ti> for each Ti. If Ui is a specialization of reference_wrapper, then Vi is Ui::type&, otherwise Vi is Ui.
template <class T1, class T2>
struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
tuple_element<0, pair<T1, T2>>::type
tuple_element<1, pair<T1, T2>>::type
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;
Returns: If I == 0 returns a reference to p.first; if I == 1 returns a reference to p.second; otherwise the program is ill-formed.
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;
struct piecewise_construct_t {
explicit piecewise_construct_t() = default;
};
inline constexpr piecewise_construct_t piecewise_construct{};
The struct piecewise_construct_t is an empty structure 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.
This subclause 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. See [pairs].
namespace std { // [tuple.tuple], class template tuple template <class... Types> class tuple; // [tuple.creation], tuple creation functions inline constexpr unspecified ignore; template <class... TTypes> constexpr tuple<VTypes...> make_tuple(TTypes&&...); template <class... TTypes> constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept; template<class... TTypes> constexpr tuple<TTypes&...> tie(TTypes&...) noexcept; template <class... Tuples> constexpr tuple<CTypes...> tuple_cat(Tuples&&...); // [tuple.apply], calling a function with a tuple of arguments template <class F, class Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t); template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t); // [tuple.helper], tuple helper classes template <class T> class tuple_size; // not defined template <class T> class tuple_size<const T>; template <class T> class tuple_size<volatile T>; template <class T> class tuple_size<const volatile T>; template <class... Types> class tuple_size<tuple<Types...>>; template <size_t I, class T> class tuple_element; // not defined template <size_t I, class T> class tuple_element<I, const T>; template <size_t I, class T> class tuple_element<I, volatile T>; template <size_t I, class T> class tuple_element<I, const volatile T>; template <size_t I, class... Types> class 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, class... UTypes> constexpr bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, class... UTypes> constexpr bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, class... UTypes> constexpr bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, class... UTypes> constexpr bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, class... UTypes> constexpr bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&); // [tuple.traits], allocator-related traits template <class... Types, class Alloc> struct uses_allocator<tuple<Types...>, Alloc>; // [tuple.special], specialized algorithms template <class... Types> void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below); // [tuple.helper], tuple helper classes template <class T> inline constexpr size_t tuple_size_v = tuple_size<T>::value; }
namespace std { template <class... Types> class tuple { public: // [tuple.cnstr], tuple construction EXPLICIT constexpr tuple(); EXPLICIT constexpr tuple(const Types&...); // only if sizeof...(Types) >= 1 template <class... UTypes> EXPLICIT constexpr tuple(UTypes&&...); // only if sizeof...(Types) >= 1 tuple(const tuple&) = default; tuple(tuple&&) = default; template <class... UTypes> EXPLICIT constexpr tuple(const tuple<UTypes...>&); template <class... UTypes> EXPLICIT constexpr tuple(tuple<UTypes...>&&); template <class U1, class U2> EXPLICIT constexpr tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2 template <class U1, class U2> EXPLICIT constexpr tuple(pair<U1, U2>&&); // only if sizeof...(Types) == 2 // allocator-extended constructors template <class Alloc> tuple(allocator_arg_t, const Alloc& a); template <class Alloc> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, const tuple&); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, tuple&&); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); template <class Alloc, class U1, class U2> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template <class Alloc, class U1, class U2> EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // [tuple.assign], tuple assignment tuple& operator=(const tuple&); tuple& operator=(tuple&&) noexcept(see below); template <class... UTypes> tuple& operator=(const tuple<UTypes...>&); template <class... UTypes> tuple& operator=(tuple<UTypes...>&&); template <class U1, class U2> tuple& operator=(const pair<U1, U2>&); // only if sizeof...(Types) == 2 template <class U1, class U2> tuple& operator=(pair<U1, U2>&&); // only if sizeof...(Types) == 2 // [tuple.swap], tuple swap void swap(tuple&) 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...>; }
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 shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function. The defaulted move and copy constructor of tuple<> shall be constexpr functions.
The destructor of tuple shall be a trivial destructor if (is_trivially_destructible_v<Types> && ...) is true.
In the constructor descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, Ti be the ith type in Types, and Ui be the ith type in a template parameter pack named UTypes, where indexing is zero-based.
EXPLICIT constexpr tuple();
Remarks: This constructor shall not participate in overload resolution unless is_default_constructible_v<Ti> is true for all i. [ Note: This behavior can be implemented by a constructor template with default template arguments. — end note ] The constructor is explicit if and only if Ti is not implicitly default-constructible for at least one i. [ Note: This behavior can be implemented with a trait that checks whether a const Ti& can be initialized with {}. — end note ]
EXPLICIT constexpr tuple(const Types&...);
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) >= 1 and is_copy_constructible_v<Ti> is true for all i. The constructor is explicit if and only if is_convertible_v<const Ti&, Ti> is false for at least one i.
template <class... UTypes> EXPLICIT constexpr tuple(UTypes&&... u);
Effects: Initializes the elements in the tuple with the corresponding value in std::forward<UTypes>(u).
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == sizeof...(UTypes) and sizeof...(Types) >= 1 and is_constructible_v<Ti, Ui&&> is true for all i. The constructor is explicit if and only if is_convertible_v<Ui&&, Ti> is false for at least one i.
tuple(const tuple& u) = default;
tuple(tuple&& u) = default;
template <class... UTypes> EXPLICIT constexpr tuple(const tuple<UTypes...>& u);
Remarks: This constructor shall not participate in overload resolution unless
sizeof...(Types) == sizeof...(UTypes) and
is_constructible_v<Ti, const Ui&> is true for all i, and
sizeof...(Types) != 1, or
(when Types... expands to T and UTypes... expands to U)
!is_convertible_v<const tuple<U>&, T> && !is_constructible_v<T, const tuple<U>&>
&& !is_same_v<T, U>
is true.
The constructor is explicit if and only if is_convertible_v<const Ui&, Ti> is false for at least one i.
template <class... UTypes> EXPLICIT constexpr tuple(tuple<UTypes...>&& u);
Remarks: This constructor shall not participate in overload resolution unless
sizeof...(Types) == sizeof...(UTypes), and
is_constructible_v<Ti, Ui&&> is true for all i, and
sizeof...(Types) != 1, or
(when Types... expands to T and UTypes... expands to U)
!is_convertible_v<tuple<U>, T> && !is_constructible_v<T, tuple<U>> &&
!is_same_v<T, U>
is true.
The constructor is explicit if and only if is_convertible_v<Ui&&, Ti> is false for at least one i.
template <class U1, class U2> EXPLICIT constexpr tuple(const pair<U1, U2>& u);
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2, is_constructible_v<T0, const U1&> is true and is_constructible_v<T1, const U2&> is true.
The constructor is explicit if and only if is_convertible_v<const U1&, T0> is false or is_convertible_v<const U2&, T1> is false.
template <class U1, class U2> EXPLICIT constexpr tuple(pair<U1, U2>&& u);
Effects: Initializes the first element with std::forward<U1>(u.first) and the second element with std::forward<U2>(u.second).
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2, is_constructible_v<T0, U1&&> is true and is_constructible_v<T1, U2&&> is true.
The constructor is explicit if and only if is_convertible_v<U1&&, T0> is false or is_convertible_v<U2&&, T1> is false.
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a);
template <class Alloc>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
template <class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, const tuple&);
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, tuple&&);
template <class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template <class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template <class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template <class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction.
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, Ti be the ith type in Types, and Ui be the ith type in a template parameter pack named UTypes, where indexing is zero-based.
tuple& operator=(const tuple& u);
Remarks: This operator shall be defined as deleted unless is_copy_assignable_v<Ti> is true for all i.
tuple& operator=(tuple&& u) noexcept(see below);
Remarks: This operator shall be defined as deleted unless is_move_assignable_v<Ti> is true for all i.
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_move_assignable_v<Ti>
where Ti is the ith type in Types.
template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == sizeof...(UTypes) and is_assignable_v<Ti&, const Ui&> is true for all i.
template <class... UTypes> tuple& operator=(tuple<UTypes...>&& u);
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<Ti&, Ui&&> == true for all i and sizeof...(Types) == sizeof...(UTypes).
template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
Effects: Assigns u.first to the first element of *this and u.second to the second element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and is_assignable_v<T0&, const U1&> is true for the first type T0 in Types and is_assignable_v<T1&, const U2&> is true for the second type T1 in Types.
template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
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.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and is_assignable_v<T0&, U1&&> is true for the first type T0 in Types and is_assignable_v<T1&, U2&&> is true for the second type T1 in Types.
void swap(tuple& rhs) noexcept(see below);
Requires: Each element in *this shall be swappable with ([swappable.requirements]) the corresponding element in rhs.
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_swappable_v<Ti>
where Ti is the ith type in Types.
In the function descriptions that follow, the members of a parameter pack XTypes are denoted by Xi for i in [0, sizeof...(XTypes)) in order, where indexing is zero-based.
template<class... TTypes>
constexpr tuple<VTypes...> make_tuple(TTypes&&... t);
The pack VTypes is defined as follows. Let Ui be decay_t<Ti> for each Ti in TTypes. If Ui is a specialization of reference_wrapper, then Vi in VTypes is Ui::type&, otherwise Vi is Ui.
[ Example:
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 variables, 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).
template<class... TTypes>
constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
Returns: tuple<TTypes&...>(t...). When an argument in t is ignore, assigning any value to the corresponding tuple element has no effect.
[ Example: 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 <class... Tuples>
constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
In the following paragraphs, let Ti be the ith type in Tuples, Ui be remove_reference_t<Ti>, and tpi be the ith parameter in the function parameter pack tpls, where all indexing is zero-based.
Requires: For all i, Ui shall be the type cvi tuple<Argsi...>, where cvi is the (possibly empty) ith cv-qualifier-seq and Argsi is the parameter pack representing the element types in Ui. Let Aik be the kth type in Argsi. For all Aik the following requirements shall be satisfied:
If Ti is deduced as an lvalue reference type, then is_constructible_v<Aik, cviAik&> == true, otherwise
is_constructible_v<Aik, cviAik&&> == true.
Remarks: The types in CTypes shall be equal to the ordered sequence of the extended types Args0..., Args1..., …, Argsn−1..., where n is equal to sizeof...(Tuples). Let ei... be the ith ordered sequence of tuple elements of the resulting tuple object corresponding to the type sequence Argsi.
Returns: A tuple object constructed by initializing the kith type element eik in ei... with
get<ki>(std::forward<Ti>(tpi))
for each valid ki and each group ei in order.
template <class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t);
Effects: Given the exposition-only function:
template <class F, class Tuple, size_t... I> constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) { // exposition only return INVOKE(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...); }
Equivalent to:
return apply_impl(std::forward<F>(f), std::forward<Tuple>(t), make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
template <class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t);
Effects: Given the exposition-only function:
template <class T, class Tuple, size_t... I>
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>(forward<Tuple>(t), make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
[ Note: The type of T must be supplied as an explicit template parameter, as it cannot be deduced from the argument list. — end note ]
template <class T> struct tuple_size;
Remarks: All specializations of tuple_size shall meet the UnaryTypeTrait requirements with a base characteristic of integral_constant<size_t, N> for some N.
template <class... Types>
class tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
template <size_t I, class... Types>
class tuple_element<I, tuple<Types...>> {
public:
using type = TI;
};
template <class T> class tuple_size<const T>;
template <class T> class tuple_size<volatile T>;
template <class T> class tuple_size<const volatile 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 of the three templates shall meet the UnaryTypeTrait requirements with a base characteristic of
integral_constant<size_t, TS::value>
Otherwise, they shall have 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: 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 three templates are available when either of the headers <array> or <utility> are included.
template <size_t I, class T> class tuple_element<I, const T>;
template <size_t I, class T> class tuple_element<I, volatile T>;
template <size_t I, class T> class tuple_element<I, const volatile T>;
Let TE denote tuple_element_t<I, T> of the cv-unqualified type T. Then each of the three templates shall meet the TransformationTrait requirements with a member typedef type that names the following type:
for the first specialization, add_const_t<TE>,
for the second specialization, add_volatile_t<TE>, and
for the third specialization, add_cv_t<TE>.
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; // Note A
template <size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>&
get(const tuple<Types...>& t) noexcept; // Note B
template <size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
[ Note A: If a 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 B: Constness is shallow. If a 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 member variables 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;
[ Example:
const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6); const int& i1 = get<int>(t); // OK. Not ambiguous. i1 == 1 const int& i2 = get<const int>(t); // OK. Not ambiguous. i2 == 2 const double& d = get<double>(t); // ERROR. ill-formed
— end example ]
template<class... TTypes, class... UTypes>
constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Requires: For all i, where 0 <= i and i < sizeof...(TTypes), get<i>(t) == get<i>(u) is a valid expression returning a type that is convertible to bool. sizeof...(TTypes) == sizeof...(UTypes).
Returns: true if get<i>(t) == get<i>(u) for all i, otherwise false. For any two zero-length tuples e and f, e == f returns true.
Effects: 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.
template<class... TTypes, class... UTypes>
constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Requires: For all i, where 0 <= i and i < sizeof...(TTypes), both get<i>(t) < get<i>(u) and get<i>(u) < get<i>(t) are valid expressions returning types that are convertible to bool. sizeof...(TTypes) == sizeof...(UTypes).
Returns: The result of a lexicographical comparison between t and u. The result is defined as: (bool)(get<0>(t) < get<0>(u)) || (!(bool)(get<0>(u) < get<0>(t)) && ttail < utail), where rtail for some tuple r is a tuple containing all but the first element of r. For any two zero-length tuples e and f, e < f returns false.
template<class... TTypes, class... UTypes>
constexpr bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
template<class... TTypes, class... UTypes>
constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
template<class... TTypes, class... UTypes>
constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
template<class... TTypes, class... UTypes>
constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
[ Note: The above definitions for comparison functions do not require ttail (or utail) to be constructed. It may not even be possible, as t and u are not required to be copy constructible. Also, all comparison functions are short circuited; they do not perform element accesses beyond what is required to determine the result of the comparison. — end note ]
template <class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc> : true_type { };
template <class... Types>
void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_swappable_v<Ti> is true for all i, where 0≤i<sizeof...(Types). The expression inside noexcept is equivalent to:
noexcept(x.swap(y))
This subclause 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.
namespace std { // [optional.optional], class template optional template <class T> class optional; // [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>&); // [optional.nullops], comparison with nullopt template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; template <class T> constexpr bool operator>=(nullopt_t, const optional<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 U&, const optional<T>&); template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&); template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&); template <class T, class U> constexpr bool operator<(const optional<T>&, const U&); template <class T, class U> constexpr bool operator<(const U&, const optional<T>&); template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&); template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&); template <class T, class U> constexpr bool operator>(const optional<T>&, const U&); template <class T, class U> constexpr bool operator>(const U&, const optional<T>&); template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&); template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&); // [optional.specalg], specialized algorithms template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below); template <class T> constexpr optional<see below> 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>>; }
template <class T> class optional { public: using value_type = T; // [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 = T> EXPLICIT constexpr optional(U&&); template <class U> EXPLICIT optional(const optional<U>&); template <class U> EXPLICIT optional(optional<U>&&); // [optional.dtor], destructor ~optional(); // [optional.assign], assignment optional& operator=(nullopt_t) noexcept; optional& operator=(const optional&); optional& operator=(optional&&) noexcept(see below); template <class U = T> optional& operator=(U&&); template <class U> optional& operator=(const optional<U>&); template <class U> optional& operator=(optional<U>&&); template <class... Args> T& emplace(Args&&...); template <class U, class... Args> T& emplace(initializer_list<U>, Args&&...); // [optional.swap], swap void swap(optional&) noexcept(see below); // [optional.observe], observers constexpr const T* operator->() const; constexpr T* operator->(); constexpr const T& operator*() const&; constexpr T& operator*() &; constexpr T&& operator*() &&; constexpr const T&& operator*() const&&; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const&; constexpr T& value() &; constexpr T&& value() &&; constexpr const T&& value() const&&; template <class U> constexpr T value_or(U&&) const&; template <class U> constexpr T value_or(U&&) &&; // [optional.mod], modifiers 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 allocated within the storage of the optional object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. The contained value shall be allocated in a region of the optional<T> storage suitably aligned for the type T. 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.
Member val is provided for exposition only. When an optional<T> object contains a value, val points to the contained value.
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
Remarks: No contained value is initialized. For every object type T these constructors shall be constexpr constructors.
constexpr optional(const optional& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression *rhs.
Remarks: This constructor shall be defined as deleted unless is_copy_constructible_v<T> is true. If is_trivially_copy_constructible_v<T> is true, this constructor shall be a constexpr constructor.
constexpr optional(optional&& rhs) noexcept(see below);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std::move(*rhs). bool(rhs) is unchanged.
Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible_v<T>. This constructor shall not participate in overload resolution unless is_move_constructible_v<T> is true. If is_trivially_move_constructible_v<T> is true, this constructor shall be a constexpr constructor.
template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std::forward<Args>(args)....
Remarks: If T's constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor. This constructor shall not participate in overload resolution unless is_constructible_v<T, Args...> is true.
template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std::forward<Args>(args)....
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<T, initializer_list<U>&, Args&&...> is true. If T's constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor.
[ Note: The following constructors are conditionally specified as explicit. This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution. — end note ]
template <class U = T> EXPLICIT constexpr optional(U&& v);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the expression std::forward<U>(v).
Remarks: If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor. This constructor shall not participate in overload resolution unless is_constructible_v<T, U&&> is true, is_same_v<decay_t<U>, in_place_t> is false, and is_same_v<optional<T>, decay_t<U>> is false. The constructor is explicit if and only if is_convertible_v<U&&, T> is false.
template <class U> EXPLICIT optional(const optional<U>& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression *rhs.
Remarks: This constructor shall not participate in overload resolution unless
is_constructible_v<T, const U&> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false, and
is_convertible_v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_convertible_v<const U&, T> is false.
template <class U> EXPLICIT optional(optional<U>&& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std::move(*rhs). bool(rhs) is unchanged.
Remarks: This constructor shall not participate in overload resolution unless
is_constructible_v<T, U&&> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false, and
is_convertible_v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_convertible_v<U&&, T> is false.
~optional();
Effects: If is_trivially_destructible_v<T> != true and *this contains a value, calls
val->T::~T()
optional<T>& operator=(nullopt_t) noexcept;
Effects: If *this contains a value, calls val->T::~T() to destroy the contained value; otherwise no effect.
optional<T>& operator=(const optional& rhs);
Effects: See Table 35.
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns *rhs to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with *rhs |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
Remarks: If any exception is thrown, the result of the expression bool(*this) 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 shall be defined as deleted unless is_copy_constructible_v<T> is true and is_copy_assignable_v<T> is true.
optional<T>& operator=(optional&& rhs) noexcept(see below);
Effects: See Table 36. The result of the expression bool(rhs) remains unchanged.
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns std::move(*rhs) to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with std::move(*rhs) |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
Remarks: The expression inside noexcept 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 bool(*this) 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. This operator shall not participate in overload resolution unless is_move_constructible_v<T> is true and is_move_assignable_v<T> is true.
template <class U = T> optional<T>& operator=(U&& v);
Effects: If *this contains a value, assigns std::forward<U>(v) to the contained value; otherwise initializes the contained value as if direct-non-list-initializing object of type T with std::forward<U>(v).
Remarks: If any exception is thrown, the result of the expression bool(*this) 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. This function shall not participate in overload resolution unless is_same_v<optional<T>, decay_t<U>> 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.
template <class U> optional<T>& operator=(const optional<U>& rhs);
Effects: See Table 37.
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns *rhs to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with *rhs |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
Remarks: If any exception is thrown, the result of the expression bool(*this) 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. This function shall not participate in overload resolution unless
is_constructible_v<T, const U&> is true,
is_assignable_v<T&, const U&> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false,
is_convertible_v<const optional<U>&&, T> 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.
template <class U> optional<T>& operator=(optional<U>&& rhs);
Effects: See Table 38. The result of the expression bool(rhs) remains unchanged.
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns std::move(*rhs) to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with std::move(*rhs) |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
Remarks: If any exception is thrown, the result of the expression bool(*this) 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. This function shall not participate in overload resolution unless
is_constructible_v<T, U> is true,
is_assignable_v<T&, U> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false,
is_convertible_v<const optional<U>&&, T> 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.
template <class... Args> T& emplace(Args&&... args);
Effects: Calls *this = nullopt. Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std::forward<Args>(args)....
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed.
template <class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Effects: Calls *this = nullopt. Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std::forward<Args>(args)....
void swap(optional& rhs) noexcept(see below);
Effects: See Table 39.
*this contains a value | *this does not contain a value | |
rhs contains a value | calls swap(*(*this), *rhs) | initializes the contained value of *this as if direct-non-list-initializing an object of type T with the expression 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 | initializes the contained value of rhs as if direct-non-list-initializing an object of type T with the expression std::move(*(*this)), followed by val->T::~T(); postcondition is that *this does not contain a value and rhs contains a value | no effect |
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
If any exception is thrown, the results of the expressions bool(*this) and bool(rhs) 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.
constexpr const T* operator->() const;
constexpr T* operator->();
constexpr const T& operator*() const&;
constexpr T& operator*() &;
constexpr T&& operator*() &&;
constexpr const T&& operator*() const&&;
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr const T& value() const&;
constexpr T& value() &;
constexpr T&& value() &&;
constexpr const T&& value() const&&;
template <class U> constexpr T value_or(U&& v) const&;
Remarks: If is_copy_constructible_v<T> && is_convertible_v<U&&, T> is false, the program is ill-formed.
template <class U> constexpr T value_or(U&& v) &&;
Effects: Equivalent to:
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
struct nullopt_t{see below};
inline constexpr nullopt_t nullopt(unspecified);
The struct nullopt_t is an empty structure 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.
class bad_optional_access : public exception { public: bad_optional_access(); };
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.
bad_optional_access();
template <class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
Requires: The expression *x == *y shall be well-formed and its result shall be convertible to bool. [ Note: T need not be EqualityComparable. — end note ]
Remarks: Specializations of this function template for which *x == *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x != *y shall be well-formed and its result shall be convertible to bool.
Remarks: Specializations of this function template for which *x != *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
Remarks: Specializations of this function template for which *x < *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
Requires: The expression *x > *y shall be well-formed and its result shall be convertible to bool.
Remarks: Specializations of this function template for which *x > *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x <= *y shall be well-formed and its result shall be convertible to bool.
Remarks: Specializations of this function template for which *x <= *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x >= *y shall be well-formed and its result shall be convertible to bool.
template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept;
template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
template <class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
Requires: The expression *x == v shall be well-formed and its result shall be convertible to bool. [ Note: T need not be EqualityComparable. — end note ]
template <class T, class U> constexpr bool operator==(const U& v, const optional<T>& x);
Requires: The expression v == *x shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
Requires: The expression *x != v shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator!=(const U& v, const optional<T>& x);
Requires: The expression v != *x shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
template <class T, class U> constexpr bool operator<(const U& v, const optional<T>& x);
Requires: The expression v < *x shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
Requires: The expression *x <= v shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator<=(const U& v, const optional<T>& x);
Requires: The expression v <= *x shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
Requires: The expression *x > v shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator>(const U& v, const optional<T>& x);
Requires: The expression v > *x shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
Requires: The expression *x >= v shall be well-formed and its result shall be convertible to bool.
template <class T, class U> constexpr bool operator>=(const U& v, const optional<T>& x);
Requires: The expression v >= *x shall be well-formed and its result shall be convertible to bool.
template <class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless is_move_constructible_v<T> is true and is_swappable_v<T> is true.
template <class T> constexpr optional<decay_t<T>> make_optional(T&& v);
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);
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 bool(o) == true, then hash<optional<T>>()(o) shall evaluate 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.
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> struct variant_size<volatile T>; template <class T> struct variant_size<const volatile T>; template <class T> inline 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> struct variant_alternative<I, volatile T>; template <size_t I, class T> struct variant_alternative<I, const volatile 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...>&); template <size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&); template <size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&); template <size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&); template <class T, class... Types> constexpr T& get(variant<Types...>&); template <class T, class... Types> constexpr T&& get(variant<Types...>&&); template <class T, class... Types> constexpr const T& get(const variant<Types...>&); template <class T, class... Types> constexpr const T&& get(const variant<Types...>&&); 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...>&); // [variant.visit], visitation template <class Visitor, class... Variants> constexpr see below visit(Visitor&&, Variants&&...); // [variant.monostate], class monostate struct monostate; // [variant.monostate.relops], monostate relational operators constexpr bool operator<(monostate, monostate) noexcept; constexpr bool operator>(monostate, monostate) noexcept; constexpr bool operator<=(monostate, monostate) noexcept; constexpr bool operator>=(monostate, monostate) noexcept; constexpr bool operator==(monostate, monostate) noexcept; constexpr bool operator!=(monostate, monostate) noexcept; // [variant.specalg], specialized algorithms template <class... Types> 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>; // [variant.traits], allocator-related traits template <class T, class Alloc> struct uses_allocator; template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc>; }
namespace std { template <class... Types> class variant { public: // [variant.ctor], constructors constexpr variant() noexcept(see below); variant(const variant&); 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&&...); // allocator-extended constructors template <class Alloc> variant(allocator_arg_t, const Alloc&); template <class Alloc> variant(allocator_arg_t, const Alloc&, const variant&); template <class Alloc> variant(allocator_arg_t, const Alloc&, variant&&); template <class Alloc, class T> variant(allocator_arg_t, const Alloc&, T&&); template <class Alloc, class T, class... Args> variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, Args&&...); template <class Alloc, class T, class U, class... Args> variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, initializer_list<U>, Args&&...); template <class Alloc, size_t I, class... Args> variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, Args&&...); template <class Alloc, size_t I, class U, class... Args> variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, initializer_list<U>, Args&&...); // [variant.dtor], destructor ~variant(); // [variant.assign], assignment variant& operator=(const variant&); variant& operator=(variant&&) noexcept(see below); template <class T> variant& operator=(T&&) noexcept(see below); // [variant.mod], modifiers template <class T, class... Args> T& emplace(Args&&...); template <class T, class U, class... Args> T& emplace(initializer_list<U>, Args&&...); template <size_t I, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(Args&&...); template <size_t I, class U, class... Args> 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 void swap(variant&) noexcept(see below); }; }
Any instance of variant at any given time either holds a value of one of its alternative types, or it 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 allocated within the storage of the variant object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value. The contained value shall be allocated in a region of the variant storage suitably aligned for all types in Types.... It is implementation-defined whether over-aligned types are supported.
In the descriptions that follow, let i be in the range [0, sizeof...(Types)), and Ti be the ith type in Types....
constexpr variant() noexcept(see below);
Remarks: This function shall be constexpr if and only if the value-initialization of the alternative type T0 would satisfy the requirements for a constexpr function. The expression inside noexcept is equivalent to is_nothrow_default_constructible_v<T0>. This function shall not participate in overload resolution unless is_default_constructible_v<T0> is true. [ Note: See also class monostate. — end note ]
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.
Remarks: This function shall not participate in overload resolution unless is_copy_constructible_v<Ti> is true for all i.
variant(variant&& w) noexcept(see below);
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.
Remarks: The expression inside noexcept is equivalent to the logical AND of is_nothrow_move_constructible_v<Ti> for all i. This function shall not participate in overload resolution unless is_move_constructible_v<Ti> is true for all i.
template <class T> constexpr variant(T&& t) noexcept(see below);
Let Tj be a type that is determined as follows: build an imaginary function FUN(Ti) for each alternative type Ti. The overload FUN(Tj) selected by overload resolution for the expression FUN(std::forward<T>(t)) defines the alternative Tj which is the type of the contained value after construction.
Effects: Initializes *this to hold the alternative type Tj and direct-initializes the contained value as if direct-non-list-initializing it with std::forward<T>(t).
Remarks: This function shall not participate in overload resolution unless is_same_v<decay_t<T>, variant> is false, unless decay_t<T> is neither a specialization of in_place_type_t nor a specialization of in_place_index_t, unless is_constructible_v<Tj, T> is true, and unless the expression FUN(std::forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.
[ Note:
variant<string, string> v("abc");
is ill-formed, as both alternative types have an equally viable constructor for the argument. — end note ]
The expression inside noexcept is equivalent to is_nothrow_constructible_v<Tj, T>. If Tj's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std::forward<Args>(args)....
Remarks: This function shall not participate in overload resolution unless there is exactly one occurrence of T in Types... and is_constructible_v<T, Args...> is true. If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <class T, class U, class... Args>
constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std::forward<Args>(args)....
Remarks: This function shall not participate in overload resolution unless there is exactly one occurrence of T in Types... and is_constructible_v<T, initializer_list<U>&, Args...> is true. If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type TI with the arguments std::forward<Args>(args)....
template <size_t I, class U, class... Args>
constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type TI with the arguments il, std::forward<Args>(args)....
// allocator-extended constructors
template <class Alloc>
variant(allocator_arg_t, const Alloc& a);
template <class Alloc>
variant(allocator_arg_t, const Alloc& a, const variant& v);
template <class Alloc>
variant(allocator_arg_t, const Alloc& a, variant&& v);
template <class Alloc, class T>
variant(allocator_arg_t, const Alloc& a, T&& t);
template <class Alloc, class T, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, Args&&... args);
template <class Alloc, class T, class U, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>,
initializer_list<U> il, Args&&... args);
template <class Alloc, size_t I, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, Args&&... args);
template <class Alloc, size_t I, class U, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>,
initializer_list<U> il, Args&&... args);
Effects: Equivalent to the preceding constructors except that the contained value is constructed with uses-allocator construction.
~variant();
variant& operator=(const variant& rhs);
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<Tj> or !is_nothrow_move_constructible_v<Tj> is true, equivalent to emplace<j>(get<j>(rhs)). Otherwise,
equivalent to operator=(variant(rhs)).
Remarks: This function shall not participate in overload resolution unless is_copy_constructible_v<Ti> && is_copy_assignable_v<Ti> is true for all i.
variant& operator=(variant&& rhs) noexcept(see below);
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))).
Remarks: This function shall not participate in overload resolution unless is_move_constructible_v<Ti> && is_move_assignable_v<Ti> is true for all i. The expression inside noexcept is equivalent to: is_nothrow_move_constructible_v<Ti> && is_nothrow_move_assignable_v<Ti> for all i.
If an exception is thrown during the call to Tj's move construction (with j being rhs.index()), the variant will hold no value.
If an exception is thrown during the call to Tj's move assignment, the state of the contained value is as defined by the exception safety guarantee of Tj's move assignment; index() will be j.
template <class T> variant& operator=(T&& t) noexcept(see below);
Let Tj be a type that is determined as follows: build an imaginary function FUN(Ti) for each alternative type Ti. The overload FUN(Tj) selected by overload resolution for the expression FUN(std::forward<T>(t)) defines the alternative Tj which is the type of the contained value after assignment.
Effects:
If *this holds a Tj, assigns std::forward<T>(t) to the value contained in *this. Otherwise,
if is_nothrow_constructible_v<Tj, T> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to emplace<j>(std::forward<T>(t)). Otherwise,
equivalent to operator=(variant(std::forward<T>(t))).
Postconditions: holds_alternative<Tj>(*this) is true, with Tj selected by the imaginary function overload resolution described above.
Remarks: This function shall not participate in overload resolution unless is_same_v<decay_t<T>, variant> is false, unless is_assignable_v<Tj&, T> && is_constructible_v<Tj, T> is true, and unless the expression FUN(std::forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.
[ Note:
variant<string, string> v; v = "abc";
is ill-formed, as both alternative types have an equally viable constructor for the argument. — end note ]
The expression inside noexcept is equivalent to:
is_nothrow_assignable_v<Tj&, T> && is_nothrow_constructible_v<Tj, 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 might not hold a value.
template <class T, class... Args> T& emplace(Args&&... args);
Remarks: This function shall not participate in overload resolution unless is_constructible_v<T, Args...> is true, and T occurs exactly once in Types....
template <class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Remarks: This function shall not participate in overload resolution unless is_constructible_v<T, initializer_list<U>&, Args...> is true, and T occurs exactly once in Types....
template <size_t I, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
Effects: Destroys the currently contained value if valueless_by_exception() is false. Then initializes the contained value as if direct-non-list-initializing a value of type TI with the arguments std::forward<Args>(args)....
Remarks: This function shall not participate in overload resolution unless is_constructible_v<TI, Args...> is true. If an exception is thrown during the initialization of the contained value, the variant might not hold a value.
template <size_t I, class U, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
Effects: Destroys the currently contained value if valueless_by_exception() is false. Then initializes the contained value as if direct-non-list-initializing a value of type TI with the arguments il, std::forward<Args>(args)....
constexpr bool valueless_by_exception() const noexcept;
[ Note: A variant might not hold a 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;
void swap(variant& rhs) noexcept(see below);
Requires: Lvalues of type Ti shall be swappable ([swappable.requirements]) and is_move_constructible_v<Ti> shall be true for all i.
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 Ti or Tj 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 Ti 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 expression inside noexcept is equivalent to the logical AND of is_nothrow_move_constructible_v<Ti> && is_nothrow_swappable_v<Ti> for all i.
template <class T> struct variant_size;
Remarks: All specializations of variant_size shall meet the UnaryTypeTrait requirements with a base characteristic of integral_constant<size_t, N> for some N.
template <class T> class variant_size<const T>;
template <class T> class variant_size<volatile T>;
template <class T> class variant_size<const volatile T>;
Let VS denote variant_size<T> of the cv-unqualified type T. Then each of the three templates shall meet the UnaryTypeTrait requirements 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> class variant_alternative<I, const T>;
template <size_t I, class T> class variant_alternative<I, volatile T>;
template <size_t I, class T> class variant_alternative<I, const volatile T>;
Let VA denote variant_alternative<I, T> of the cv-unqualified type T. Then each of the three templates shall meet the TransformationTrait requirements with a member typedef type that names the following type:
for the first specialization, add_const_t<VA::type>,
for the second specialization, add_volatile_t<VA::type>, and
for the third specialization, add_cv_t<VA::type>.
variant_alternative<I, variant<Types...>>::type
template <class T, class... Types>
constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
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);
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);
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;
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;
template <class... Types>
constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) == get<i>(w) is a valid expression returning a type 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);
Requires: get<i>(v) != get<i>(w) is a valid expression returning a type 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);
Requires: get<i>(v) < get<i>(w) is a valid expression returning a type 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);
Requires: get<i>(v) > get<i>(w) is a valid expression returning a type 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);
Requires: get<i>(v) <= get<i>(w) is a valid expression returning a type 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);
Requires: get<i>(v) >= get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
template <class Visitor, class... Variants>
constexpr see below visit(Visitor&& vis, Variants&&... vars);
Requires: The expression in the Effects: element shall be a valid expression of the same type and value category, for all combinations of alternative types of all variants. Otherwise, the program is ill-formed.
Effects: Let is... be vars.index().... Returns INVOKE(forward<Visitor>(vis), get<is>( forward<Variants>(vars))...);.
Remarks: The return type is the common type of all possible INVOKE expressions of the Effects: element.
struct monostate{};
constexpr bool operator<(monostate, monostate) noexcept { return false; }
constexpr bool operator>(monostate, monostate) noexcept { return false; }
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
constexpr bool operator>=(monostate, monostate) noexcept { return true; }
constexpr bool operator==(monostate, monostate) noexcept { return true; }
constexpr bool operator!=(monostate, monostate) noexcept { return false; }
template <class... Types>
void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_move_constructible_v<Ti> && is_swappable_v<Ti> is true for all i. The expression inside noexcept is equivalent to noexcept(v.swap(w)).
class bad_variant_access : public exception { public: bad_variant_access() noexcept; 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.
bad_variant_access() noexcept;
const char* what() const noexcept override;
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]).
template <class... Types, class Alloc>
struct uses_allocator<variant<Types...>, Alloc> : true_type { };
This section describes components that C++ programs may use to perform operations on objects of a discriminated type.
[ Note: The discriminated type may 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 ]
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; }
class bad_any_cast : public bad_cast { public: const char* what() const noexcept override; };
const char* what() const noexcept override;
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).
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 satisfies 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 both have a value and the contained values are equivalent.
Implementations should avoid the use of dynamically allocated memory for a small contained value. [ Example: where the object constructed is holding only an int. — end example ] Such small-object optimization shall only be applied to types T for which is_nothrow_move_constructible_v<T> is true.
constexpr any() noexcept;
any(const any& other);
Effects: If other.has_value() is false, constructs an object that has no value. Otherwise, equivalent to any(in_place<T>, any_cast<const T&>(other)) where T is the type of the contained object.
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 object of other, or contains an object of the same type constructed from the contained object of other considering that contained object as an rvalue.
template<class T>
any(T&& value);
Effects: Constructs an object of type any that contains an object of type VT direct-initialized with std::forward<T>(value).
Remarks: This constructor shall not participate in overload resolution unless 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.
template <class T, class... Args>
explicit any(in_place_type_t<T>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std::forward<Args>(args)....
Remarks: This constructor shall not participate in overload resolution unless is_copy_constructible_v<VT> is true and is_constructible_v<VT, Args...> is true.
template <class T, class U, class... Args>
explicit any(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std::forward<Args>(args)....
Remarks: This constructor shall not participate in overload resolution unless is_copy_constructible_v<VT> is true and is_constructible_v<VT, initializer_list<U>&, Args...> is true.
~any();
any& operator=(const any& rhs);
any& operator=(any&& rhs) noexcept;
Postconditions: The state of *this is equivalent to the original state of rhs and rhs is left in a valid but otherwise unspecified state.
template<class T>
any& operator=(T&& rhs);
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.
Remarks: This operator shall not participate in overload resolution unless VT is not the same type as any and is_copy_constructible_v<VT> is true.
template <class T, class... Args>
decay_t<T>& emplace(Args&&... args);
Effects: Calls reset(). Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std::forward<Args>(args)....
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. This function shall not participate in overload resolution unless is_copy_constructible_v<VT> is true and is_constructible_v<VT, Args...> is true.
template <class T, class U, class... Args>
decay_t<T>& emplace(initializer_list<U> il, Args&&... args);
Effects: Calls reset(). Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std::forward<Args>(args)....
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. The function shall not participate in overload resolution unless is_copy_constructible_v<VT> is true and is_constructible_v<VT, initializer_list<U>&, Args...> is true.
void reset() noexcept;
void swap(any& rhs) noexcept;
bool has_value() const noexcept;
const type_info& type() const noexcept;
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);
Requires: For the first overload, is_constructible_v<ValueType, const U&> is true. For the second overload, is_constructible_v<ValueType, U&> is true. For the third overload, is_constructible_v<ValueType, U> is true. Otherwise the program is ill-formed.
Returns: For the first and second overload, static_cast<ValueType>(*any_cast<U>(&operand)). For the third overload, static_cast<ValueType>(std::move(*any_cast<U>(&operand))).
[ Example:
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;
Returns: If operand != nullptr && operand->type() == typeid(T), a pointer to the object contained by operand; otherwise, nullptr.
#include <string> #include <iosfwd> // for istream, ostream, see [iosfwd.syn] namespace std { template <size_t N> class bitset; // [bitset.operators], bitset operators template <size_t N> bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept; template <size_t N> bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept; template <size_t N> 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); }
namespace std { template<size_t N> class bitset { public: // bit reference: class reference { friend class bitset; reference() noexcept; public: ~reference() noexcept; reference& operator=(bool x) noexcept; // for b[i] = x; reference& operator=(const reference&) noexcept; // for b[i] = b[j]; bool operator~() const noexcept; // flips the bit operator bool() const noexcept; // for x = b[i]; 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> 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> explicit bitset( const charT* str, typename basic_string<charT>::size_type n = basic_string<charT>::npos, charT zero = charT('0'), charT one = charT('1')); // [bitset.members], bitset operations bitset<N>& operator&=(const bitset<N>& rhs) noexcept; bitset<N>& operator|=(const bitset<N>& rhs) noexcept; bitset<N>& operator^=(const bitset<N>& rhs) noexcept; bitset<N>& operator<<=(size_t pos) noexcept; bitset<N>& operator>>=(size_t pos) noexcept; bitset<N>& set() noexcept; bitset<N>& set(size_t pos, bool val = true); bitset<N>& reset() noexcept; bitset<N>& reset(size_t pos); bitset<N> operator~() const noexcept; bitset<N>& flip() noexcept; bitset<N>& flip(size_t pos); // element access: constexpr bool operator[](size_t pos) const; // for b[i]; reference operator[](size_t pos); // for b[i]; unsigned long to_ulong() const; unsigned long long to_ullong() const; template <class charT = char, class traits = char_traits<charT>, class Allocator = allocator<charT>> basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const; size_t count() const noexcept; constexpr size_t size() const noexcept; bool operator==(const bitset<N>& rhs) const noexcept; bool operator!=(const bitset<N>& rhs) const noexcept; bool test(size_t pos) const; bool all() const noexcept; bool any() const noexcept; bool none() const noexcept; bitset<N> operator<<(size_t pos) const noexcept; bitset<N> operator>>(size_t pos) 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 this subclause can report three kinds of errors, each associated with a distinct exception:
an invalid-argument error is associated with exceptions of type invalid_argument;
an out-of-range error is associated with exceptions of type out_of_range;
an overflow error is associated with exceptions of type overflow_error.
constexpr bitset() noexcept;
constexpr bitset(unsigned long long val) noexcept;
Effects: Constructs an object of class bitset<N>, initializing 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 of unsigned long long. If M < N, the remaining bit positions are initialized to zero.
template <class charT, class traits, class Allocator>
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'));
Effects: Determines the effective length rlen of the initializing string as the smaller of n and str.size() - pos.
The function then throws invalid_argument if any of the rlen characters in str beginning at position pos is other than zero or one. The function uses traits::eq() to compare the character values.
Otherwise, the function constructs an object of class bitset<N>, initializing 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.
template <class charT>
explicit bitset(
const charT* str,
typename basic_string<charT>::size_type n = basic_string<charT>::npos,
charT zero = charT('0'), charT one = charT('1'));
bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
Effects: Clears each bit in *this for which the corresponding bit in rhs is clear, and leaves all other bits unchanged.
bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
Effects: Sets each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
Effects: Toggles each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
bitset<N>& operator<<=(size_t pos) noexcept;
bitset<N>& operator>>=(size_t pos) noexcept;
bitset<N>& set() noexcept;
bitset<N>& set(size_t pos, bool val = true);
Effects: Stores a new value in the bit at position pos in *this. If val is nonzero, the stored value is one, otherwise it is zero.
bitset<N>& reset() noexcept;
bitset<N>& reset(size_t pos);
bitset<N> operator~() const noexcept;
bitset<N>& flip() noexcept;
bitset<N>& flip(size_t pos);
unsigned long to_ulong() const;
unsigned long long to_ullong() const;
template <class charT = char,
class traits = char_traits<charT>,
class Allocator = allocator<charT>>
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.
size_t count() const noexcept;
constexpr size_t size() const noexcept;
bool operator==(const bitset<N>& rhs) const noexcept;
Returns: true if the value of each bit in *this equals the value of the corresponding bit in rhs.
bool operator!=(const bitset<N>& rhs) const noexcept;
bool test(size_t pos) const;
bool all() const noexcept;
bool any() const noexcept;
bool none() const noexcept;
bitset<N> operator<<(size_t pos) const noexcept;
bitset<N> operator>>(size_t pos) const noexcept;
constexpr bool operator[](size_t pos) const;
bitset<N>::reference operator[](size_t pos);
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val).
template <size_t N> struct hash<bitset<N>>;
The specialization is enabled ([unord.hash]).
bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
template <class charT, class traits, size_t N>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
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:
If no characters are stored in str, calls is.setstate(ios_base::failbit) (which may throw ios_base::failure ([iostate.flags])).
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]).
The header <memory> defines several types and function templates that describe properties of pointers and pointer-like types, manage memory for containers and other template types, destroy objects, and construct multiple objects in uninitialized memory buffers ([pointer.traits]–[specialized.algorithms]). The header also defines the templates unique_ptr, shared_ptr, weak_ptr, and various function templates that operate on objects of these types ([smartptr]).
namespace std { // [pointer.traits], pointer traits template <class Ptr> struct pointer_traits; template <class T> struct pointer_traits<T*>; // [util.dynamic.safety], pointer safety enum class pointer_safety { relaxed, preferred, strict }; void declare_reachable(void* p); template <class T> T* undeclare_reachable(T* p); void declare_no_pointers(char* p, size_t n); void undeclare_no_pointers(char* p, size_t n); pointer_safety get_pointer_safety() noexcept; // [ptr.align], pointer alignment function void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // [allocator.tag], allocator argument tag struct allocator_arg_t { explicit allocator_arg_t() = default; }; inline constexpr allocator_arg_t allocator_arg{}; // [allocator.uses], uses_allocator template <class T, class Alloc> struct uses_allocator; // [allocator.traits], allocator traits template <class Alloc> struct allocator_traits; // [default.allocator], the default allocator template <class T> class allocator; template <class T, class U> bool operator==(const allocator<T>&, const allocator<U>&) noexcept; template <class T, class U> bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // [specialized.algorithms], specialized algorithms template <class T> constexpr T* addressof(T& r) noexcept; template <class T> const T* addressof(const T&&) = delete; template <class ForwardIterator> void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); template <class ExecutionPolicy, class ForwardIterator> void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); template <class ExecutionPolicy, class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, Size n); template <class ForwardIterator> void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); template <class ExecutionPolicy, class ForwardIterator> void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class Size> ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); template <class ExecutionPolicy, class ForwardIterator, class Size> ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, Size n); template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); template <class ExecutionPolicy, class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, InputIterator last, ForwardIterator result); template <class InputIterator, class Size, class ForwardIterator> ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator> ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, Size n, ForwardIterator result); template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); template <class ExecutionPolicy, class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, InputIterator last, ForwardIterator result); template <class InputIterator, class Size, class ForwardIterator> pair<InputIterator, ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator> pair<InputIterator, ForwardIterator> uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, Size n, ForwardIterator result); template <class ForwardIterator, class T> void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); template <class ExecutionPolicy, class ForwardIterator, class T> void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, ForwardIterator last, const T& x); template <class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); template <class ExecutionPolicy, class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, Size n, const T& x); template <class T> void destroy_at(T* location); template <class ForwardIterator> void destroy(ForwardIterator first, ForwardIterator last); template <class ExecutionPolicy, class ForwardIterator> void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class Size> ForwardIterator destroy_n(ForwardIterator first, Size n); template <class ExecutionPolicy, class ForwardIterator, class Size> ForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] ForwardIterator first, Size n); // [unique.ptr], class template unique_ptr template <class T> struct default_delete; template <class T> struct default_delete<T[]>; template <class T, class D = default_delete<T>> class unique_ptr; template <class T, class D> class unique_ptr<T[], D>; template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args); template <class T> unique_ptr<T> make_unique(size_t n); template <class T, class... Args> unspecified make_unique(Args&&...) = delete; template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; template <class T1, class D1, class T2, class D2> bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T1, class D1, class T2, class D2> bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T1, class D1, class T2, class D2> bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T1, class D1, class T2, class D2> bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T1, class D1, class T2, class D2> bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; template <class T, class D> bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; template <class T, class D> bool operator<(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<(nullptr_t, const unique_ptr<T, D>& y); template <class T, class D> bool operator<=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<=(nullptr_t, const unique_ptr<T, D>& y); template <class T, class D> bool operator>(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>(nullptr_t, const unique_ptr<T, D>& y); template <class T, class D> bool operator>=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>=(nullptr_t, const unique_ptr<T, D>& y); // [util.smartptr.weak.bad], class bad_weak_ptr class bad_weak_ptr; // [util.smartptr.shared], class template shared_ptr template<class T> class shared_ptr; // [util.smartptr.shared.create], shared_ptr creation template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args); template<class T, class A, class... Args> shared_ptr<T> allocate_shared(const A& a, Args&&... args); // [util.smartptr.shared.cmp], shared_ptr comparisons template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U> bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U> bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U> bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U> bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template <class T> bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; template <class T> bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; template <class T> bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; template <class T> bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; template <class T> bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; template <class T> bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; // [util.smartptr.shared.spec], shared_ptr specialized algorithms template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; // [util.smartptr.shared.cast], shared_ptr casts template<class T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U> shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U> shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept; // [util.smartptr.getdeleter], shared_ptr get_deleter template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept; // [util.smartptr.shared.io], shared_ptr I/O template<class E, class T, class Y> basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p); // [util.smartptr.weak], class template weak_ptr template<class T> class weak_ptr; // [util.smartptr.weak.spec], weak_ptr specialized algorithms template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; // [util.smartptr.ownerless], class template owner_less template<class T = void> struct owner_less; // [util.smartptr.enab], class template enable_shared_from_this template<class T> class enable_shared_from_this; // [util.smartptr.shared.atomic], shared_ptr atomic access template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p); template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p); template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo); template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r); template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r); template<class T> shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); template<class T> bool atomic_compare_exchange_weak( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); template<class T> bool atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); template<class T> bool atomic_compare_exchange_weak_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure); template<class T> bool atomic_compare_exchange_strong_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure); // [util.smartptr.hash], hash support template <class T> struct hash; template <class T, class D> struct hash<unique_ptr<T, D>>; template <class T> struct hash<shared_ptr<T>>; // [allocator.uses.trait], uses_allocator template <class T, class Alloc> inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; }
The class template pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
namespace std { template <class Ptr> struct pointer_traits { using pointer = Ptr; using element_type = see below; using difference_type = see below; template <class U> using rebind = see below; static pointer pointer_to(see below r); }; template <class T> struct pointer_traits<T*> { using pointer = T*; using element_type = T; using difference_type = ptrdiff_t; template <class U> using rebind = U*; static pointer pointer_to(see below r) noexcept; }; }
using element_type = see below;
Type: Ptr::element_type if the qualified-id Ptr::element_type is valid and denotes a type ([temp.deduct]); otherwise, T if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the specialization is ill-formed.
using difference_type = see below;
Type: Ptr::difference_type if the qualified-id Ptr::difference_type is valid and denotes a type ([temp.deduct]); otherwise, ptrdiff_t.
template <class U> using rebind = see below;
Alias template: Ptr::rebind<U> if the qualified-id Ptr::rebind<U> is valid and denotes a type ([temp.deduct]); otherwise, SomePointer<U, Args> if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind is ill-formed.
static pointer pointer_traits::pointer_to(see below r);
static pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
Remarks: If element_type is cv void, the type of r is unspecified; otherwise, it is element_type&.
Returns: The first member function returns a pointer to r obtained by calling Ptr::pointer_to(r) through which indirection is valid; an instantiation of this function is ill-formed if Ptr does not have a matching pointer_to static member function. The second member function returns addressof(r).
A complete object is declared reachable while the number of calls to declare_reachable with an argument referencing the object exceeds the number of calls to undeclare_reachable with an argument referencing the object.
void declare_reachable(void* p);
Requires: p shall be a safely-derived pointer or a null pointer value.
Effects: If p is not null, the complete object referenced by p is subsequently declared reachable ([basic.stc.dynamic.safety]).
Throws: May throw bad_alloc if the system cannot allocate additional memory that may be required to track objects declared reachable.
template <class T> T* undeclare_reachable(T* p);
Requires: If p is not null, the complete object referenced by p shall have been previously declared reachable, and shall be live ([basic.life]) from the time of the call until the last undeclare_reachable(p) call on the object.
[ Note: It is expected that calls to declare_reachable(p) will consume a small amount of memory in addition to that occupied by the referenced object until the matching call to undeclare_reachable(p) is encountered. Long running programs should arrange that calls are matched. — end note ]
void declare_no_pointers(char* p, size_t n);
Requires: No bytes in the specified range are currently registered with declare_no_pointers(). If the specified range is in an allocated object, then it must be entirely within a single allocated object. The object must be live until the corresponding undeclare_no_pointers() call. [ Note: In a garbage-collecting implementation, the fact that a region in an object is registered with declare_no_pointers() should not prevent the object from being collected. — end note ]
Effects: The n bytes starting at p no longer contain traceable pointer locations, independent of their type. Hence indirection through a pointer located there is undefined if the object it points to was created by global operator new and not previously declared reachable. [ Note: This may be used to inform a garbage collector or leak detector that this region of memory need not be traced. — end note ]
[ Note: Under some conditions implementations may need to allocate memory. However, the request can be ignored if memory allocation fails. — end note ]
void undeclare_no_pointers(char* p, size_t n);
Effects: Unregisters a range registered with declare_no_pointers() for destruction. It must be called before the lifetime of the object ends.
pointer_safety get_pointer_safety() noexcept;
Returns: pointer_safety::strict if the implementation has strict pointer safety. It is implementation-defined whether get_pointer_safety returns pointer_safety::relaxed or pointer_safety::preferred if the implementation has relaxed pointer safety.221
pointer_safety::preferred might be returned to indicate that a leak detector is running so that the program can avoid spurious leak reports.
void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
Effects: If it is possible to fit size bytes of storage aligned by alignment into the buffer pointed to by ptr with length space, the function updates ptr to represent the first possible address of such storage and decreases space by the number of bytes used for alignment. Otherwise, the function does nothing.
Returns: A null pointer if the requested aligned buffer would not fit into the available space, otherwise the adjusted value of ptr.
namespace std {
struct allocator_arg_t { explicit allocator_arg_t() = default; };
inline constexpr allocator_arg_t allocator_arg{};
}
The allocator_arg_t struct is an empty structure type used as a unique type to disambiguate constructor and function overloading. Specifically, several types (see tuple [tuple]) have constructors with allocator_arg_t as the first argument, immediately followed by an argument of a type that satisfies the Allocator requirements.
template <class T, class Alloc> struct uses_allocator;
Remarks: Automatically detects whether T has a nested allocator_type that is convertible from Alloc. Meets the BinaryTypeTrait requirements. The implementation shall provide a definition that is derived from true_type if the qualified-id T::allocator_type is valid and denotes a type ([temp.deduct]) and is_convertible_v<Alloc, T::allocator_type> != false, otherwise it shall be derived from false_type. A program may specialize this template to derive from true_type for a user-defined type T that does not have a nested allocator_type but nonetheless can be constructed with an allocator where either:
the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or
the last argument of a constructor has type Alloc.
Uses-allocator construction with allocator Alloc refers to the construction of an object obj of type T, using constructor arguments v1, v2, ..., vN of types V1, V2, ..., VN, respectively, and an allocator alloc of type Alloc, according to the following rules:
if uses_allocator_v<T, Alloc> is false and is_constructible_v<T, V1, V2, ..., VN> is true, then obj is initialized as obj(v1, v2, ..., vN);
otherwise, if uses_allocator_v<T, Alloc> is true and is_constructible_v<T, allocator_arg_t, Alloc, V1, V2, ..., VN> is true, then obj is initialized as obj(allocator_arg, alloc, v1, v2, ..., vN);
otherwise, if uses_allocator_v<T, Alloc> is true and is_constructible_v<T, V1, V2, ..., VN, Alloc> is true, then obj is initialized as obj(v1, v2, ..., vN, alloc);
otherwise, the request for uses-allocator construction is ill-formed. [ Note: An error will result if uses_allocator_v<T, Alloc> is true but the specific constructor does not take an allocator. This definition prevents a silent failure to pass the allocator to an element. — end note ]
The class template allocator_traits supplies a uniform interface to all allocator types. An allocator cannot be a non-class type, however, even if allocator_traits supplies the entire required interface. [ Note: Thus, it is always possible to create a derived class from an allocator. — end note ]
namespace std { template <class Alloc> struct allocator_traits { using allocator_type = Alloc; using value_type = typename Alloc::value_type; using pointer = see below; using const_pointer = see below; using void_pointer = see below; using const_void_pointer = see below; using difference_type = see below; using size_type = see below; using propagate_on_container_copy_assignment = see below; using propagate_on_container_move_assignment = see below; using propagate_on_container_swap = see below; using is_always_equal = see below; template <class T> using rebind_alloc = see below; template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; static pointer allocate(Alloc& a, size_type n); static pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static void deallocate(Alloc& a, pointer p, size_type n); template <class T, class... Args> static void construct(Alloc& a, T* p, Args&&... args); template <class T> static void destroy(Alloc& a, T* p); static size_type max_size(const Alloc& a) noexcept; static Alloc select_on_container_copy_construction(const Alloc& rhs); }; }
using pointer = see below;
Type: Alloc::pointer if the qualified-id Alloc::pointer is valid and denotes a type ([temp.deduct]); otherwise, value_type*.
using const_pointer = see below;
Type: Alloc::const_pointer if the qualified-id Alloc::const_pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_traits<pointer>::rebind<const value_type>.
using void_pointer = see below;
Type: Alloc::void_pointer if the qualified-id Alloc::void_pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_traits<pointer>::rebind<void>.
using const_void_pointer = see below;
Type: Alloc::const_void_pointer if the qualified-id Alloc::const_void_pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_traits<pointer>::rebind<const void>.
using difference_type = see below;
Type: Alloc::difference_type if the qualified-id Alloc::difference_type is valid and denotes a type ([temp.deduct]); otherwise, pointer_traits<pointer>::difference_type.
using size_type = see below;
Type: Alloc::size_type if the qualified-id Alloc::size_type is valid and denotes a type ([temp.deduct]); otherwise, make_unsigned_t<difference_type>.
using propagate_on_container_copy_assignment = see below;
Type: Alloc::propagate_on_container_copy_assignment if the qualified-id Alloc::propagate_on_container_copy_assignment is valid and denotes a type ([temp.deduct]); otherwise false_type.
using propagate_on_container_move_assignment = see below;
Type: Alloc::propagate_on_container_move_assignment if the qualified-id Alloc::propagate_on_container_move_assignment is valid and denotes a type ([temp.deduct]); otherwise false_type.
using propagate_on_container_swap = see below;
Type: Alloc::propagate_on_container_swap if the qualified-id Alloc::propagate_on_container_swap is valid and denotes a type ([temp.deduct]); otherwise false_type.
using is_always_equal = see below;
Type: Alloc::is_always_equal if the qualified-id Alloc::is_always_equal is valid and denotes a type ([temp.deduct]); otherwise is_empty<Alloc>::type.
template <class T> using rebind_alloc = see below;
Alias template: Alloc::rebind<T>::other if the qualified-id Alloc::rebind<T>::other is valid and denotes a type ([temp.deduct]); otherwise, Alloc<T, Args> if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind_alloc is ill-formed.
static pointer allocate(Alloc& a, size_type n);
static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
static void deallocate(Alloc& a, pointer p, size_type n);
template <class T, class... Args>
static void construct(Alloc& a, T* p, Args&&... args);
Effects: Calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed; otherwise, invokes ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...).
template <class T>
static void destroy(Alloc& a, T* p);
static size_type max_size(const Alloc& a) noexcept;
Returns: a.max_size() if that expression is well-formed; otherwise, numeric_limits<size_type>::max()/sizeof(value_type).
static Alloc select_on_container_copy_construction(const Alloc& rhs);
All specializations of the default allocator satisfy the allocator completeness requirements ([allocator.requirements.completeness]).
namespace std { template <class T> class allocator { public: using value_type = T; using propagate_on_container_move_assignment = true_type; using is_always_equal = true_type; allocator() noexcept; allocator(const allocator&) noexcept; template <class U> allocator(const allocator<U>&) noexcept; ~allocator(); T* allocate(size_t n); void deallocate(T* p, size_t n); }; }
Except for the destructor, member functions of the default allocator shall not introduce data races as a result of concurrent calls to those member functions from different threads. Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.
T* allocate(size_t n);
Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropriately for objects of type T.
Remarks: the storage is obtained by calling ::operator new, but it is unspecified when or how often this function is called.
void deallocate(T* p, size_t n);
Requires: p shall be a pointer value obtained from allocate(). n shall equal the value passed as the first argument to the invocation of allocate which returned p.
Remarks: Uses ::operator delete, but it is unspecified when this function is called.
Throughout this subclause, the names of template parameters are used to express type requirements.
If an algorithm's template parameter is named InputIterator, the template argument shall satisfy the requirements of an input iterator.
If an algorithm's template parameter is named ForwardIterator, the template argument shall satisfy the requirements of a forward iterator, and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.
Unless otherwise specified, if an exception is thrown in the following algorithms there are no effects.
template <class T> constexpr T* addressof(T& r) noexcept;
Returns: The actual address of the object or function referenced by r, even in the presence of an overloaded operator&.
Remarks: An expression addressof(E) is a constant subexpression if E is an lvalue constant subexpression.
template <class ForwardIterator>
void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first != last; ++first) ::new (static_cast<void*>(addressof(*first))) typename iterator_traits<ForwardIterator>::value_type;
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
template <class ForwardIterator>
void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first != last; ++first) ::new (static_cast<void*>(addressof(*first))) typename iterator_traits<ForwardIterator>::value_type();
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result);
Effects: As if by:
for (; first != last; ++result, (void) ++first) ::new (static_cast<void*>(addressof(*result))) typename iterator_traits<ForwardIterator>::value_type(*first);
template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
ForwardIterator result);
Effects: As if by:
for ( ; n > 0; ++result, (void) ++first, --n) { ::new (static_cast<void*>(addressof(*result))) typename iterator_traits<ForwardIterator>::value_type(*first); }
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move(InputIterator first, InputIterator last,
ForwardIterator result);
Effects: Equivalent to:
for (; first != last; (void)++result, ++first) ::new (static_cast<void*>(addressof(*result))) typename iterator_traits<ForwardIterator>::value_type(std::move(*first)); return result;
Remarks: If an exception is thrown, some objects in the range [first, last) are left in a valid but unspecified state.
template <class InputIterator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator>
uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
Effects: Equivalent to:
for (; n > 0; ++result, (void) ++first, --n) ::new (static_cast<void*>(addressof(*result))) typename iterator_traits<ForwardIterator>::value_type(std::move(*first)); return {first,result};
template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x);
Effects: As if by:
for (; first != last; ++first) ::new (static_cast<void*>(addressof(*first))) typename iterator_traits<ForwardIterator>::value_type(x);
template <class ForwardIterator, class Size, class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
template <class T>
void destroy_at(T* location);
template <class ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last);
template <class ForwardIterator, class Size>
ForwardIterator destroy_n(ForwardIterator first, Size n);
void* aligned_alloc(size_t alignment, size_t size);
void* calloc(size_t nmemb, size_t size);
void* malloc(size_t size);
void* realloc(void* ptr, size_t size);
Remarks: These functions do not attempt to allocate storage by calling ::operator new() ([support.dynamic]).
Storage allocated directly with these functions is implicitly declared reachable (see [basic.stc.dynamic.safety]) on allocation, ceases to be declared reachable on deallocation, and need not cease to be declared reachable as the result of an undeclare_reachable() call. [ Note: This allows existing C libraries to remain unaffected by restrictions on pointers that are not safely derived, at the expense of providing far fewer garbage collection and leak detection options for malloc()-allocated objects. It also allows malloc() to be implemented with a separate allocation arena, bypassing the normal declare_reachable() implementation. The above functions should never intentionally be used as a replacement for declare_reachable(), and newly written code is strongly encouraged to treat memory allocated with these functions as though it were allocated with operator new. — end note ]
void free(void* ptr);
See also: ISO C 7.22.3.
A unique pointer is an object that owns another object and manages that other object through a pointer. More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose of p when u is itself destroyed (e.g., when leaving block scope ([stmt.dcl])). In this context, u is said to own p.
The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct invocation results in p's appropriate disposition (typically its deletion).
Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request, u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned object via the associated deleter before such replacement is considered completed.
Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of such a transfer, the following postconditions hold:
u2.p is equal to the pre-transfer u.p,
u.p is equal to nullptr, and
if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer associated deleter before the ownership transfer is considered complete. [ Note: A deleter's state need never be copied, only moved or swapped as ownership is transferred. — end note ]
Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable. The template parameter T of unique_ptr may be an incomplete type.
[ Note: The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function. — end note ]
namespace std {
template<class T> struct default_delete;
template<class T> struct default_delete<T[]>;
template<class T, class D = default_delete<T>> class unique_ptr;
template<class T, class D> class unique_ptr<T[], D>;
template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
template<class T> unique_ptr<T> make_unique(size_t n);
template<class T, class... Args> unspecified make_unique(Args&&...) = delete;
template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
template<class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template<class T1, class D1, class T2, class D2>
bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template<class T1, class D1, class T2, class D2>
bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template<class T1, class D1, class T2, class D2>
bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template<class T1, class D1, class T2, class D2>
bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template<class T1, class D1, class T2, class D2>
bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
template <class T, class D>
bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator<(nullptr_t, const unique_ptr<T, D>& y);
template <class T, class D>
bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
template <class T, class D>
bool operator>(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator>(nullptr_t, const unique_ptr<T, D>& y);
template <class T, class D>
bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
}
The class template default_delete serves as the default deleter (destruction policy) for the class template unique_ptr.
namespace std { template <class T> struct default_delete { constexpr default_delete() noexcept = default; template <class U> default_delete(const default_delete<U>&) noexcept; void operator()(T*) const; }; }
template <class U> default_delete(const default_delete<U>& other) noexcept;
Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible to T*.
void operator()(T* ptr) const;
namespace std { template <class T> struct default_delete<T[]> { constexpr default_delete() noexcept = default; template <class U> default_delete(const default_delete<U[]>&) noexcept; template <class U> void operator()(U* ptr) const; }; }
template <class U> default_delete(const default_delete<U[]>& other) noexcept;
Remarks: This constructor shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].
template <class U> void operator()(U* ptr) const;
namespace std { template <class T, class D = default_delete<T>> class unique_ptr { public: using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.single.ctor], constructors constexpr unique_ptr() noexcept; explicit unique_ptr(pointer p) noexcept; unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept; unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept; // [unique.ptr.single.dtor], destructor ~unique_ptr(); // [unique.ptr.single.asgn], assignment unique_ptr& operator=(unique_ptr&& u) noexcept; template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // [unique.ptr.single.observers], observers add_lvalue_reference_t<T> operator*() const; pointer operator->() const noexcept; pointer get() const noexcept; deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept; explicit operator bool() const noexcept; // [unique.ptr.single.modifiers], modifiers pointer release() noexcept; void reset(pointer p = pointer()) noexcept; void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; }
The default type for the template parameter D is default_delete. A client-supplied template argument D shall be a function object type, lvalue reference to function, or lvalue reference to function object type for which, given a value d of type D and a value ptr of type unique_ptr<T, D>::pointer, the expression d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
If the qualified-id remove_reference_t<D>::pointer is valid and denotes a type ([temp.deduct]), then unique_ptr<T, D>::pointer shall be a synonym for remove_reference_t<D>::pointer. Otherwise unique_ptr<T, D>::pointer shall be a synonym for element_type*. The type unique_ptr<T, D>::pointer shall satisfy the requirements of NullablePointer.
[ Example: Given an allocator type X ([allocator.requirements]) and letting A be a synonym for allocator_traits<X>, the types A::pointer, A::const_pointer, A::void_pointer, and A::const_void_pointer may be used as unique_ptr<T, D>::pointer. — end example ]
constexpr unique_ptr() noexcept;
constexpr unique_ptr(nullptr_t) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible, and that construction shall not throw an exception.
Effects: Constructs a unique_ptr object that owns nothing, value-initializing the stored pointer and the stored deleter.
Remarks: If is_pointer_v<deleter_type> is true or is_default_constructible_v<deleter_type> is false, this constructor shall not participate in overload resolution.
explicit unique_ptr(pointer p) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible, and that construction shall not throw an exception.
Effects: Constructs a unique_ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter.
Remarks: If is_pointer_v<deleter_type> is true or is_default_constructible_v<deleter_type> is false, this constructor shall not participate in overload resolution. If class template argument deduction ([over.match.class.deduct]) would select the function template corresponding to this constructor, then the program is ill-formed.
unique_ptr(pointer p, see below d1) noexcept;
unique_ptr(pointer p, see below d2) noexcept;
The signature of these constructors depends upon whether D is a reference type. If D is a non-reference type A, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, A&& d) noexcept;
If D is an lvalue reference type A&, then the signatures are:
unique_ptr(pointer p, A& d) noexcept; unique_ptr(pointer p, A&& d) = delete;
If D is an lvalue reference type const A&, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, const A&& d) = delete;
Effects: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and initializing the deleter from std::forward<decltype(d)>(d).
Remarks: These constructors shall not participate in overload resolution unless is_constructible_v<D, decltype(d)> is true.
Postconditions: get() == p. get_deleter() returns a reference to the stored deleter. If D is a reference type then get_deleter() returns a reference to the lvalue d.
Remarks: If class template argument deduction ([over.match.class.deduct]) would select a function template corresponding to either of these constructors, then the program is ill-formed.
[ Example:
D d; unique_ptr<int, D> p1(new int, D()); // D must be MoveConstructible unique_ptr<int, D> p2(new int, d); // D must be CopyConstructible unique_ptr<int, D&> p3(new int, d); // p3 holds a reference to d unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined // with reference deleter type
— end example ]
unique_ptr(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible. Construction of the deleter from an rvalue of type D shall not throw an exception.
Effects: Constructs a unique_ptr by transferring ownership from u to *this. If D is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter. [ Note: The deleter constructor can be implemented with std::forward<D>. — end note ]
Postconditions: get() yields the value u.get() yielded before the construction. get_deleter() returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a reference type then get_deleter() and u.get_deleter() both reference the same lvalue deleter.
template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the deleter from an lvalue of type E shall be well formed and shall not throw an exception.
Remarks: This constructor shall not participate in overload resolution unless:
unique_ptr<U, E>::pointer is implicitly convertible to pointer,
U is not an array type, and
either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
Effects: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter. [ Note: The deleter constructor can be implemented with std::forward<E>. — end note ]
~unique_ptr();
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions. [ Note: The use of default_delete requires T to be a complete type. — end note ]
unique_ptr& operator=(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D is a reference type; remove_reference_t<D> shall satisfy the CopyAssignable requirements and assignment of the deleter from an lvalue of type D shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_deleter() = std::forward<D>(u.get_deleter()).
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_deleter() = std::forward<E>(u.get_deleter()).
unique_ptr& operator=(nullptr_t) noexcept;
add_lvalue_reference_t<T> operator*() const;
pointer operator->() const noexcept;
pointer get() const noexcept;
deleter_type& get_deleter() noexcept;
const deleter_type& get_deleter() const noexcept;
explicit operator bool() const noexcept;
pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: Assigns p to the stored pointer, and then if and only if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p). [ Note: The order of these operations is significant because the call to get_deleter() may destroy *this. — end note ]
Postconditions: get() == p. [ Note: The postcondition does not hold if the call to get_deleter() destroys *this since this->get() is no longer a valid expression. — end note ]
void swap(unique_ptr& u) noexcept;
namespace std { template <class T, class D> class unique_ptr<T[], D> { public: using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.runtime.ctor], constructors constexpr unique_ptr() noexcept; template <class U> explicit unique_ptr(U p) noexcept; template <class U> unique_ptr(U p, see below d) noexcept; template <class U> unique_ptr(U p, see below d) noexcept; unique_ptr(unique_ptr&& u) noexcept; template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; // destructor ~unique_ptr(); // assignment unique_ptr& operator=(unique_ptr&& u) noexcept; template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // [unique.ptr.runtime.observers], observers T& operator[](size_t i) const; pointer get() const noexcept; deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept; explicit operator bool() const noexcept; // [unique.ptr.runtime.modifiers], modifiers pointer release() noexcept; template <class U> void reset(U p) noexcept; void reset(nullptr_t = nullptr) noexcept; void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; }
A specialization for array types is provided with a slightly altered interface.
Conversions between different types of unique_ptr<T[], D> that would be disallowed for the corresponding pointer-to-array types, and conversions to or from the non-array forms of unique_ptr, produce an ill-formed program.
Pointers to types derived from T are rejected by the constructors, and by reset.
The observers operator* and operator-> are not provided.
The indexing observer operator[] is provided.
The default deleter will call delete[].
template <class U> explicit unique_ptr(U p) noexcept;
This constructor behaves the same as the constructor in the primary template that takes a single parameter of type pointer except that it additionally shall not participate in overload resolution unless
U is the same type as pointer, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
template <class U> unique_ptr(U p, see below d) noexcept;
template <class U> unique_ptr(U p, see below d) noexcept;
These constructors behave the same as the constructors in the primary template that take a parameter of type pointer and a second parameter except that they shall not participate in overload resolution unless either
U is the same type as pointer,
U is nullptr_t, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
template <class U, class E>
unique_ptr(unique_ptr<U, E>&& u) noexcept;
This constructor behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_ptr<U, E>:
U is an array type, and
pointer is the same type as element_type*, and
UP::pointer is the same type as UP::element_type*, and
UP::element_type(*)[] is convertible to element_type(*)[], and
either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
[ Note: This replaces the overload-resolution specification of the primary template — end note ]
template <class U, class E>
unique_ptr& operator=(unique_ptr<U, E>&& u)noexcept;
This operator behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_ptr<U, E>:
U is an array type, and
pointer is the same type as element_type*, and
UP::pointer is the same type as UP::element_type*, and
UP::element_type(*)[] is convertible to element_type(*)[], and
is_assignable_v<D&, E&&> is true.
[ Note: This replaces the overload-resolution specification of the primary template — end note ]
T& operator[](size_t i) const;
void reset(nullptr_t p = nullptr) noexcept;
template <class U> void reset(U p) noexcept;
This function behaves the same as the reset member of the primary template, except that it shall not participate in overload resolution unless either
U is the same type as pointer, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
template <class T> unique_ptr<T> make_unique(size_t n);
Remarks: This function shall not participate in overload resolution unless T is an array of unknown bound.
template <class T, class... Args> unspecified make_unique(Args&&...) = delete;
template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
Remarks: This function shall not participate in overload resolution unless is_swappable_v<D> is true.
template <class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Requires: Let CT denote
common_type_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>
Then the specialization less<CT> shall be a function object type that induces a strict weak ordering on the pointer values.
Remarks: If unique_ptr<T1, D1>::pointer is not implicitly convertible to CT or unique_ptr<T2, D2>::pointer is not implicitly convertible to CT, the program is ill-formed.
template <class T1, class D1, class T2, class D2>
bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator==(nullptr_t, const unique_ptr<T, D>& x) noexcept;
template <class T, class D>
bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator!=(nullptr_t, const unique_ptr<T, D>& x) noexcept;
template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator<(nullptr_t, const unique_ptr<T, D>& x);
Requires: The specialization less<unique_ptr<T, D>::pointer> shall be a function object type that induces a strict weak ordering on the pointer values.
Returns:
The first function template returns
less<unique_ptr<T, D>::pointer>()(x.get(),
nullptr).
The second function template returns
less<unique_ptr<T, D>::pointer>()(nullptr, x.get()).
template <class T, class D>
bool operator>(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator>(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns nullptr < x. The second function template returns x < nullptr.
template <class T, class D>
bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns !(nullptr < x). The second function template returns !(x < nullptr).
template <class T, class D>
bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns !(x < nullptr). The second function template returns !(nullptr < x).
namespace std { class bad_weak_ptr : public exception { public: bad_weak_ptr() noexcept; }; }
bad_weak_ptr() noexcept;
The weak_ptr class template stores a weak reference to an object that is already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the member function lock.
namespace std { template<class T> class weak_ptr { public: using element_type = T; // [util.smartptr.weak.const], constructors constexpr weak_ptr() noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept; weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; weak_ptr(weak_ptr&& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // [util.smartptr.weak.dest], destructor ~weak_ptr(); // [util.smartptr.weak.assign], assignment weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept; weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // [util.smartptr.weak.mod], modifiers void swap(weak_ptr& r) noexcept; void reset() noexcept; // [util.smartptr.weak.obs], observers long use_count() const noexcept; bool expired() const noexcept; shared_ptr<T> lock() const noexcept; template<class U> bool owner_before(const shared_ptr<U>& b) const; template<class U> bool owner_before(const weak_ptr<U>& b) const; }; template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>; // [util.smartptr.weak.spec], specialized algorithms template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; }
Specializations of weak_ptr shall be CopyConstructible and CopyAssignable, allowing their use in standard containers. The template parameter T of weak_ptr may be an incomplete type.
constexpr weak_ptr() noexcept;
weak_ptr(const weak_ptr& r) noexcept;
template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
Remarks: The second and third constructors shall not participate in overload resolution unless Y* is compatible with T*.
Effects: If r is empty, constructs an empty weak_ptr object; otherwise, constructs a weak_ptr object that shares ownership with r and stores a copy of the pointer stored in r.
weak_ptr(weak_ptr&& r) noexcept;
template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
~weak_ptr();
weak_ptr& operator=(const weak_ptr& r) noexcept;
template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Remarks: The implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary.
weak_ptr& operator=(weak_ptr&& r) noexcept;
template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
void swap(weak_ptr& r) noexcept;
void reset() noexcept;
long use_count() const noexcept;
Returns: 0 if *this is empty; otherwise, the number of shared_ptr instances that share ownership with *this.
bool expired() const noexcept;
shared_ptr<T> lock() const noexcept;
template<class U> bool owner_before(const shared_ptr<U>& b) const;
template<class U> bool owner_before(const weak_ptr<U>& b) const;
Returns: An unspecified value such that
x.owner_before(y) defines a strict weak ordering as defined in [alg.sorting];
under the equivalence relation defined by owner_before, !a.owner_before(b) && !b.owner_before(a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.
template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
The class template owner_less allows ownership-based mixed comparisons of shared and weak pointers.
namespace std {
template<class T = void> struct owner_less;
template<class T> struct owner_less<shared_ptr<T>> {
bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
};
template<class T> struct owner_less<weak_ptr<T>> {
bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
};
template<> struct owner_less<void> {
template<class T, class U>
bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
template<class T, class U>
bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
template<class T, class U>
bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
template<class T, class U>
bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
using is_transparent = unspecified;
};
}
operator()(x, y) shall return x.owner_before(y). [ Note: Note that
operator() defines a strict weak ordering as defined in [alg.sorting];
under the equivalence relation defined by operator(), !operator()(a, b) && !operator()(b, a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.
— end note ]
A class T can inherit from enable_shared_from_this<T> to inherit the shared_from_this member functions that obtain a shared_ptr instance pointing to *this.
[ Example:
struct X: public enable_shared_from_this<X> { };
int main() {
shared_ptr<X> p(new X);
shared_ptr<X> q = p->shared_from_this();
assert(p == q);
assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
}
— end example ]
namespace std {
template<class T> class enable_shared_from_this {
protected:
constexpr enable_shared_from_this() noexcept;
enable_shared_from_this(const enable_shared_from_this&) noexcept;
enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
~enable_shared_from_this();
public:
shared_ptr<T> shared_from_this();
shared_ptr<T const> shared_from_this() const;
weak_ptr<T> weak_from_this() noexcept;
weak_ptr<T const> weak_from_this() const noexcept;
private:
mutable weak_ptr<T> weak_this; // exposition only
};
}
constexpr enable_shared_from_this() noexcept;
enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
shared_ptr<T> shared_from_this();
shared_ptr<T const> shared_from_this() const;
weak_ptr<T> weak_from_this() noexcept;
weak_ptr<T const> weak_from_this() const noexcept;