22 General utilities library [utilities]

22.4 Tuples [tuple]

22.4.4 Class template tuple [tuple.tuple]


22.4.4.1 General [tuple.tuple.general]

22.4.4.2 Construction [tuple.cnstr]

22.4.4.3 Assignment [tuple.assign]

22.4.4.4 swap [tuple.swap]


22.4.4.1 General [tuple.tuple.general]

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

22.4.4.2 Construction [tuple.cnstr]

In the descriptions that follow, let i be in the range [0, sizeof.(Types)) in order,
For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception.
The defaulted move and copy constructor, respectively, of tuple is a constexpr function if and only if all required element-wise initializations for move and copy, respectively, would be constexpr-suitable ([dcl.constexpr]).
The defaulted move and copy constructor of tuple<> are constexpr functions.
If is_trivially_destructible_v<
The default constructor of tuple<> is trivial.
constexpr explicit(see below) tuple();
Remarks: The expression inside explicit evaluates to true if and only if
[Note 1: 
This behavior can be implemented with a trait that checks whether a const
— end note]
constexpr explicit(see below) tuple(const Types&.) noexcept(is_nothrow_copy_constructible_v<Types> && ..);
Constraints: sizeof.(Types)  ≥ 1 and is_copy_constructible_v<
Effects: Initializes each element with the value of the corresponding parameter.
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<const Types&, Types>.>
template<class. UTypes> constexpr explicit(see below) tuple(UTypes&&. u) noexcept(is_nothrow_constructible_v<Types, UTypes> && ..);
Let disambiguating-constraint be:
  • negation<is_same<remove_cvref_t<
  • otherwise, bool_constant<!is_same_v<remove_cvref_t<
  • otherwise, true_type.
Constraints:
  • sizeof.(Types) equals sizeof.(UTypes),
  • sizeof.(Types)  ≥ 1, and
  • conjunction_v<disambiguating-constraint, is_constructible<Types, UTypes>.> is
    true.
Effects: Initializes the elements in the tuple with the corresponding value in std​::​forward<UTypes>(u).
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<UTypes, Types>.>
This constructor is defined as deleted if (reference_constructs_from_temporary_v<Types, UTypes&&> || ..) is true.
tuple(const tuple& u) = default;
Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
Effects: For all i, initializes the
template<class. UTypes> constexpr explicit(see below) tuple(tuple<UTypes..>& u); template<class. UTypes> constexpr explicit(see below) tuple(const tuple<UTypes..>& u); template<class. UTypes> constexpr explicit(see below) tuple(tuple<UTypes..>& u); template<class. UTypes> constexpr explicit(see below) tuple(const tuple<UTypes..>& u);
Constraints:
  • sizeof.(Types) equals sizeof.(UTypes), and
  • (is_constructible_v<Types, decltype(get<I>(FWD(u))> && ..) is true, and
  • either sizeof.(Types) is not 1, or (when Types.. expands to T and UTypes.. expands to U) is_convertible_v<decltype(u), T>, is_constructible_v<T, decltype(u)>, and is_same_v<T, U> are all false.
Effects: For all i, initializes the
Remarks: The expression inside explicit is equivalent to: !(is_convertible_v<decltype(get<I>(FWD(u)), Types> && ..)
The constructor is defined as deleted if (reference_constructs_from_temporary_v<Types, decltype(get<I>(FWD(u))> || ..) is true.
template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>& u); template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u); template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>& u); template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u);
Effects: Initializes the first element with get<0>(FWD(u)) and the second element with get<1>(FWD(​u)).
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<decltype(get<0>(FWD(u)),
The constructor is defined as deleted if reference_constructs_from_temporary_v<
template<tuple-like UTuple> constexpr explicit(see below) tuple(UTuple&& u);
Constraints:
  • different-from<UTuple, tuple> ([range.utility.helpers]) is true,
  • remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
  • sizeof.(Types) equals tuple_size_v<remove_cvref_t<UTuple>>,
  • (is_constructible_v<Types, decltype(get<I>(std​::​forward<UTuple>(u))> && ..) is true, and
  • either sizeof.(Types) is not 1, or (when Types.. expands to T) is_convertible_v<UTuple, T> and is_constructible_v<T, UTuple> are both false.
Effects: For all i, initializes the
Remarks: The expression inside explicit is equivalent to: !(is_convertible_v<decltype(get<I>(std::forward<UTuple>(u)), Types> && ..)
The constructor is defined as deleted if (reference_constructs_from_temporary_v<Types, decltype(get<I>(std::forward<UTuple>(u))> || ..) is true.
template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a); template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const Types&.); template<class Alloc, class. UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTypes&&.); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template<class Alloc, class. UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes..>&); template<class Alloc, class. UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes..>&); template<class Alloc, class. UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes..>&); template<class Alloc, class. UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes..>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template<class Alloc, tuple-like UTuple> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTuple&&);
Preconditions: Alloc meets the Cpp17Allocator requirements ([allocator.requirements.general]).
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction.
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,
constexpr tuple& operator=(const tuple& u);
Effects: Assigns each element of u to the corresponding element of *this.
Remarks: This operator is defined as deleted unless is_copy_assignable_v<
constexpr const tuple& operator=(const tuple& u) const;
Returns: *this.
constexpr tuple& operator=(tuple&& u) noexcept(see below);
Effects: For all i, assigns std​::​forward<
Remarks: The exception specification is equivalent to the logical and of the following expressions: is_nothrow_move_assignable_v<
constexpr const tuple& operator=(tuple&& u) const;
Effects: For all i, assigns std​::​forward<T
Returns: *this.
template<class. UTypes> constexpr tuple& operator=(const tuple<UTypes..>& u);
Effects: Assigns each element of u to the corresponding element of *this.
Returns: *this.
template<class. UTypes> constexpr const tuple& operator=(const tuple<UTypes..>& u) const;
Returns: *this.
template<class. UTypes> constexpr tuple& operator=(tuple<UTypes..>& u);
Effects: For all i, assigns std​::​forward<
Returns: *this.
template<class. UTypes> constexpr const tuple& operator=(tuple<UTypes..>& u) const;
Effects: For all i, assigns std​::​forward<U
Returns: *this.
template<class U1, class U2> constexpr 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.
Returns: *this.
template<class U1, class U2> constexpr const tuple& operator=(const pair<U1, U2>& u) const;
Effects: Assigns u.first to the first element and u.second to the second element.
Returns: *this.
template<class U1, class U2> constexpr tuple& operator=(pair<U1, U2>& u);
Effects: Assigns std​::​forward<U1>(u.first) to the first element of *this and
std​::​forward<U2>(u.second) to the second element of *this.
Returns: *this.
template<class U1, class U2> constexpr const tuple& operator=(pair<U1, U2>& u) const;
Returns: *this.
template<tuple-like UTuple> constexpr tuple& operator=(UTuple&& u);
Constraints:
  • different-from<UTuple, tuple> ([range.utility.helpers]) is true,
  • remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
  • sizeof.(Types) equals tuple_size_v<remove_cvref_t<UTuple>>, and
  • is_assignable_v<
Effects: For all i, assigns get<i>(std​::​forward<UTuple>(u)) to get<i>(*this).
Returns: *this.
template<tuple-like UTuple> constexpr const tuple& operator=(UTuple&& u) const;
Constraints:
  • different-from<UTuple, tuple> ([range.utility.helpers]) is true,
  • remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
  • sizeof.(Types) equals tuple_size_v<remove_cvref_t<UTuple>>, and
  • is_assignable_v<const
Effects: For all i, assigns get<i>(std​::​forward<UTuple>(u)) to get<i>(*this).
Returns: *this.
constexpr void swap(tuple& rhs) noexcept(see below); constexpr void swap(const tuple& rhs) const noexcept(see below);
Mandates:
  • For the first overload, (is_swappable_v<Types> && ..) is true.
  • For the second overload, (is_swappable_v<const Types> && ..) is true.
Remarks: The exception specification is equivalent to
  • (is_nothrow_swappable_v<Types> && ..) for the first overload and
  • (is_nothrow_swappable_v<const Types> && ..) for the second overload.

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

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