20 General utilities library [utilities]

20.5 Tuples [tuple]

20.5.3 Class template tuple [tuple.tuple]

20.5.3.1 Construction [tuple.cnstr]

In the descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, be the type in Types, and be the type in a template parameter pack named UTypes, where indexing is zero-based.
For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception.
The defaulted move and copy constructor, respectively, of tuple is a constexpr function if and only if all required element-wise initializations for move and copy, respectively, would satisfy the requirements for a constexpr function.
The defaulted move and copy constructor of tuple<> are constexpr functions.
If is_­trivially_­destructible_­v<> is true for all , then the destructor of tuple is trivial.
constexpr explicit(see below) tuple();
Constraints: is_­default_­constructible_­v<> is true for all i.
Effects: Value-initializes each element.
Remarks: The expression inside explicit evaluates to true if and only if is not copy-list-initializable from an empty list for at least one i.
[Note 1:
This behavior can be implemented with a trait that checks whether a const & can be initialized with {}.
— end note]
constexpr explicit(see below) tuple(const Types&...);
Constraints: and is_­copy_­constructible_­v<> is true for all i.
Effects: Initializes each element with the value of the corresponding parameter.
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<const Types&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&... u);
Constraints: sizeof...(Types) equals sizeof...(UTypes) and and is_­constructible_­v<, > is true for all i.
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>...>
tuple(const tuple& u) = default;
Mandates: is_­copy_­constructible_­v<> is true for all i.
Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
Constraints: is_­move_­constructible_­v<> is true for all i.
Effects: For all i, initializes the element of *this with std​::​forward<>(get<i>(u)).
template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u);
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes) and
  • is_­constructible_­v<, const &> is true for all i, and
  • either sizeof...(Types) is not 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>&>, and is_­same_­v<T, U> are all false.
Effects: Initializes each element of *this with the corresponding element of u.
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<const UTypes&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u);
Constraints:
  • sizeof...(Types) equals sizeof...(UTypes), and
  • is_­constructible_­v<, > is true for all i, and
  • either sizeof...(Types) is not 1, or (when Types... expands to T and UTypes... expands to U) is_­convertible_­v<tuple<U>, T>, is_­constructible_­v<T, tuple<U>>, and is_­same_­v<T, U> are all false.
Effects: For all i, initializes the element of *this with std​::​forward<>(get<i>(u)).
Remarks: The expression inside explicit is equivalent to: !conjunction_v<is_convertible<UTypes, Types>...>
template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u);
Constraints:
  • sizeof...(Types) is 2,
  • is_­constructible_­v<, const U1&> is true, and
  • is_­constructible_­v<, const U2&> is true.
Effects: Initializes the first element with u.first and the second element with u.second.
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<const U1&, > || !is_convertible_v<const U2&, >
template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&& u);
Constraints:
  • sizeof...(Types) is 2,
  • is_­constructible_­v<, U1> is true, and
  • is_­constructible_­v<, U2> is true.
Effects: Initializes the first element with std​::​forward<U1>(u.first) and the second element with std​::​forward<U2>(u.second).
Remarks: The expression inside explicit is equivalent to: !is_convertible_v<U1, > || !is_convertible_v<U2, >
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, 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 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>&&);
Preconditions: Alloc meets the Cpp17Allocator requirements (Table 36).
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction.