std::tuple::tuple(3)

NAME
std::tuple::tuple - std::tuple::tuple

Synopsis
   Defined in header <tuple>
   constexpr tuple(); (1) (since C++11)
                        (conditionally explicit)
                        (since C++11)
   tuple( const Types&... args ); (2) (constexpr since C++14)
                        (conditionally explicit)
   template< class... UTypes > (since C++11)
   tuple( UTypes&&... args ); (3) (constexpr since C++14)
                        (conditionally explicit)
   template< class... UTypes > (4) (since C++23)
   constexpr tuple( tuple<UTypes...>& other ); (conditionally explicit)
   template< class... UTypes > (since C++11)
   tuple( const tuple<UTypes...>& other ); (5) (constexpr since C++14)
                        (conditionally explicit)
   template< class... UTypes > (since C++11)
   tuple( tuple<UTypes...>&& other ); (6) (constexpr since C++14)
                        (conditionally explicit)
   template< class... UTypes > (7) (since C++23)
   constexpr tuple( const tuple<UTypes...>&& other ); (conditionally explicit)
   template< class U1, class U2 > (8) (since C++23)
   constexpr tuple( std::pair<U1, U2>& p ); (conditionally explicit)
   template< class U1, class U2 > (since C++11)
   tuple( const std::pair<U1, U2>& p ); (9) (constexpr since C++14)
                        (conditionally explicit)
   template< class U1, class U2 > (since C++11)
   tuple( std::pair<U1, U2>&& p ); (10) (constexpr since C++14)
                        (conditionally explicit)
   template< class U1, class U2 > (11) (since C++23)
   constexpr tuple( const std::pair<U1, U2>&& p ); (conditionally explicit)
   tuple( const tuple& other ) = default; (12) (since C++11)
   tuple( tuple&& other ) = default; (13) (since C++11)
   template< class Alloc > (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a ); (14) (constexpr since C++20)
                        (conditionally explicit)
   template< class Alloc >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (15) (constexpr since C++20)
                        (conditionally explicit)
   const Types&... args );
   template< class Alloc, class... UTypes >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (16) (constexpr since C++20)
                        (conditionally explicit)
   UTypes&&... args );
   template< class Alloc, class... UTypes >
                        (since C++23)
   constexpr tuple( std::allocator_arg_t, const Alloc& a, (17) (conditionally explicit)
   tuple<UTypes...>& other );
   template< class Alloc, class... UTypes >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (18) (constexpr since C++20)
                        (conditionally explicit)
   const tuple<UTypes...>& other );
   template< class Alloc, class... UTypes >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (19) (constexpr since C++20)
                        (conditionally explicit)
   tuple<UTypes...>&& other );
   template< class Alloc, class... UTypes >
                        (since C++23)
   constexpr tuple( std::allocator_arg_t, const Alloc& a, (20) (conditionally explicit)
   const tuple<UTypes...>&& other );
   template< class Alloc, class U1, class U2 >
                        (since C++23)
   constexpr tuple( std::allocator_arg_t, const Alloc& a, (21) (conditionally explicit)
   std::pair<U1, U2>& p );
   template< class Alloc, class U1, class U2 >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (22) (constexpr since C++20)
                        (conditionally explicit)
   const std::pair<U1, U2>& p );
   template< class Alloc, class U1, class U2 >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (23) (constexpr since C++20)
                        (conditionally explicit)
   std::pair<U1, U2>&& p );
   template< class Alloc, class U1, class U2 >
                        (since C++23)
   constexpr tuple( std::allocator_arg_t, const Alloc& a, (24) (conditionally explicit)
   const std::pair<U1, U2>&& p );
   template< class Alloc >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (25) (constexpr since C++20)
   const tuple& other );
   template< class Alloc >
                        (since C++11)
   tuple( std::allocator_arg_t, const Alloc& a, (26) (constexpr since C++20)
   tuple&& other );
   Constructs a new tuple.
   1) Default constructor. Value-initializes all elements, if any. The default
   constructor is trivial if sizeof...(Types) == 0.
     * This overload participates in overload resolution only if
       std::is_default_constructible<Ti>::value is true for all i
     * The constructor is explicit if and only if Ti is not copy-list-initializable
       from {} for at least one i.
   2) Direct constructor. Initializes each element of the tuple with the corresponding
   parameter.
     * This overload participates in overload resolution only if sizeof...(Types) >= 1
       and std::is_copy_constructible<Ti>::value is true for all i.
     * This constructor is explicit if and only if std::is_convertible<const Ti&,
       Ti>::value is false for at least one i.
   3) Converting constructor. Initializes each element of the tuple with the
   corresponding value in std::forward<UTypes>(args).
     * This overload participates in overload resolution only if
          * sizeof...(Types) == sizeof...(UTypes), and
          * sizeof...(Types) >= 1, and
          * std::is_constructible<Ti, Ui>::value is true for all i, and
          * let D be
            std::decay<U0>::type
            (until C++20)
            std::remove_cvref_t<U0>
            (since C++20),
               * if sizeof...(Types) == 1, then D is not tuple, otherwise,
               * if sizeof...(Types) == 2 or sizeof...(Types) == 3, then either D is
                 not std::allocator_arg_t, or T0 is std::allocator_arg_t.
     * The constructor is explicit if and only if std::is_convertible<Ui, Ti>::value is
       false for at least one i.
     * This constructor is defined as deleted if the initialization of
       any element that is a reference would bind it to a temporary (since C++23)
       object.
   4) Converting copy-constructor. For all i in sizeof...(UTypes), initializes ith
   element of the tuple with std::get<i>(other).
     * This overload participates in overload resolution only if
          * sizeof...(Types) == sizeof...(UTypes) and
          * std::is_constructible_v<Ti, Ui&> is true for all i and
          * either
               * sizeof...(Types) != 1 or
               * (when Types... expands to T and UTypes... expands to U)
                 std::is_convertible_v<tuple<U>&, T>, std::is_constructible_v<T,
                 tuple<U>&>, and std::is_same_v<T, U> are all false.
     * The constructor is explicit if and only if std::is_convertible_v<Ui&, Ti> is
       false for at least one i.
     * This constructor is defined as deleted if the initialization of any element that
       is a reference would bind it to a temporary object.
   5) Converting copy-constructor. For all i in sizeof...(UTypes), initializes ith
   element of the tuple with std::get<i>(other).
     * This overload participates in overload resolution only if
          * sizeof...(Types) == sizeof...(UTypes) and
          * std::is_constructible<Ti, const Ui&>::value is true for all i and
          * either
               * sizeof...(Types) != 1 or
               * (when Types... expands to T and UTypes... expands to U)
                 std::is_convertible<const tuple<U>&, T>::value,
                 std::is_constructible<T, const tuple<U>&>::value, and std::is_same<T,
                 U>::value are all false.
     * The constructor is explicit if and only if std::is_convertible<const Ui&,
       Ti>::value is false for at least one i.
     * This constructor is defined as deleted if the initialization of
       any element that is a reference would bind it to a temporary (since C++23)
       object.
   6) Converting move-constructor. For all i in sizeof...(UTypes), initializes ith
   element of the tuple with std::forward<Ui>(std::get<i>(other)).
     * This overload participates in overload resolution only if
          * sizeof...(Types) == sizeof...(UTypes) and
          * std::is_constructible<Ti, Ui>::value is true for all i and
          * either
               * sizeof...(Types) != 1 or
               * (when Types... expands to T and UTypes... expands to U)
                 std::is_convertible<tuple<U>, T>::value, std::is_constructible<T,
                 tuple<U>>::value, and std::is_same<T, U>::value are all false.
     * The constructor is explicit if and only if std::is_convertible<Ui, Ti>::value is
       false for at least one i.
     * This constructor is defined as deleted if the initialization of
       any element that is a reference would bind it to a temporary (since C++23)
       object.
   7) Converting move-constructor. For all i in sizeof...(UTypes), initializes ith
   element of the tuple with std::forward<const Ui>(std::get<i>(other)).
     * This overload participates in overload resolution only if
          * sizeof...(Types) == sizeof...(UTypes) and
          * std::is_constructible_v<Ti, const Ui> is true for all i and
          * either
               * sizeof...(Types) != 1 or
               * (when Types... expands to T and UTypes... expands to U)
                 std::is_convertible_v<const tuple<U>, T>, std::is_constructible_v<T,
                 const tuple<U>>, and std::is_same_v<T, U> are all false.
     * The constructor is explicit if and only if std::is_convertible_v<const Ui, Ti>
       is false for at least one i.
     * This constructor is defined as deleted if the initialization of any element that
       is a reference would bind it to a temporary object.
   8) Pair copy constructor. Constructs a 2-element tuple with the first element
   constructed from p.first and the second element from p.second
     * This overload participates in overload resolution only if sizeof...(Types) == 2
       and std::is_constructible_v<T0, U1&> and std::is_constructible_v<T1, U2&> are
       both true
     * The constructor is explicit if and only if std::is_convertible_v<U1&, T0> or
       std::is_convertible_v<U2&, T1> is false.
     * This constructor is defined as deleted if the initialization of any element that
       is a reference would bind it to a temporary object.
   9) Pair copy constructor. Constructs a 2-element tuple with the first element
   constructed from p.first and the second element from p.second
     * This overload participates in overload resolution only if sizeof...(Types) == 2
       and std::is_constructible<T0,const U1&>::value and std::is_constructible<T1,
       const U2&>::value are both true
     * The constructor is explicit if and only if std::is_convertible<const U1&,
       T0>::value or std::is_convertible<const U2&, T1>::value is false.
     * This constructor is defined as deleted if the initialization of
       any element that is a reference would bind it to a temporary (since C++23)
       object.
   10) Pair move constructor. Constructs a 2-element tuple with the first element
   constructed from std::forward<U1>(p.first) and the second element from
   std::forward<U2>(p.second)
     * This overload participates in overload resolution only if sizeof...(Types) == 2
       and std::is_constructible<T0, U1>::value and std::is_constructible<T1,
       U2>::value are both true
     * The constructor is explicit if and only if std::is_convertible<U1, T0>::value or
       std::is_convertible<U2, T1>::value is false.
     * This constructor is defined as deleted if the initialization of
       any element that is a reference would bind it to a temporary (since C++23)
       object.
   11) Pair move constructor. Constructs a 2-element tuple with the first element
   constructed from std::forward<const U1>(p.first) and the second element from
   std::forward<const U2>(p.second)
     * This overload participates in overload resolution only if sizeof...(Types) == 2
       and std::is_constructible_v<T0, const U1> and std::is_constructible_v<T1, const
       U2> are both true
     * The constructor is explicit if and only if std::is_convertible_v<U1, T0> or
       std::is_convertible_v<U2, T1> is false.
     * This constructor is defined as deleted if the initialization of any element that
       is a reference would bind it to a temporary object.
   12) Implicitly-defined copy constructor. Initializes each element of the tuple with
   the corresponding element of other.
     * This constructor is constexpr if every operation it performs is constexpr. For
       the empty tuple std::tuple<>, it is constexpr.
     * std::is_copy_constructible<Ti>::value must be true for all i, otherwise
       the behavior is undefined
       (until C++20)
       the program is ill-formed
       (since C++20).
   13) Implicitly-defined move constructor. Initializes each ith element of the tuple
   with std::forward<Ui>(std::get<i>(other)).
     * This constructor is constexpr if every operation it performs is constexpr. For
       the empty tuple std::tuple<>, it is constexpr.
     * std::is_move_constructible<Ti>::value must be true for all i, otherwise
       the behavior is undefined
       (until C++20)
       this overload does not participate in overload resolution
       (since C++20).
   14-26) Identical to (1-13) except each element is created by uses-allocator
   construction, that is, the Allocator object a is passed as an additional argument to
   the constructor of each element for which std::uses_allocator<Ui, Alloc>::value is
   true.

Parameters
   args - values used to initialize each element of the tuple
   other - a tuple of values used to initialize each element of the tuple
   p - pair of values used to initialize both elements of this 2-tuple
   a - allocator to use in uses-allocator construction

Notes
   Conditionally-explicit constructors make it possible to construct a tuple in
   copy-initialization context using list-initialization syntax:
 std::tuple<int, int> foo_tuple()
 {
   return {1, -1}; // Error before N4387
   return std::make_tuple(1, -1); // Always works
 }
   Note that if some element of the list is not implicitly convertible to the
   corresponding element of the target tuple, the constructors become explicit:
 using namespace std::chrono;
 void launch_rocket_at(std::tuple<hours, minutes, seconds>);
 launch_rocket_at({hours(1), minutes(2), seconds(3)}); // OK
 launch_rocket_at({1, 2, 3}); // Error: int is not implicitly convertible to duration
 launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK

Example
// Run this code
 #include <iomanip>
 #include <iostream>
 #include <memory>
 #include <string>
 #include <tuple>
 #include <type_traits>
 #include <vector>
 // helper function to print a vector to a stream
 template<class Os, class T>
 Os& operator<< (Os& os, std::vector<T> const& v)
 {
     os << '{';
     for (auto i{v.size()}; const T& e : v)
         os << e << (--i ? "," : "");
     return os << '}';
 }
 template<class T>
 void print_single(T const& v)
 {
     if constexpr (std::is_same_v<T, std::decay_t<std::string>>)
         std::cout << std::quoted(v);
     else if constexpr (std::is_same_v<std::decay_t<T>, char>)
         std::cout << "'" << v << "'";
     else
         std::cout << v;
 }
 // helper function to print a tuple of any size
 template<class Tuple, std::size_t N>
 struct TuplePrinter {
     static void print(const Tuple& t)
     {
         TuplePrinter<Tuple, N-1>::print(t);
         std::cout << ", ";
         print_single(std::get<N-1>(t));
     }
 };
 template<class Tuple>
 struct TuplePrinter<Tuple, 1>{
     static void print(const Tuple& t)
     {
         print_single(std::get<0>(t));
     }
 };
 template<class... Args>
 void print(const std::tuple<Args...>& t)
 {
     std::cout << "(";
     TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
     std::cout << ")\n";
 }
 // end helper function
 int main()
 {
     std::tuple<int, std::string, double> t1;
     std::cout << "Value-initialized, t1: "; print(t1);
     std::tuple<int, std::string, double> t2{42, "Test", -3.14};
     std::cout << "Initialized with values, t2: "; print(t2);
     std::tuple<char, std::string, int> t3{t2};
     std::cout << "Implicitly converted, t3: "; print(t3);
     std::tuple<int, double> t4{std::make_pair(42, 3.14)};
     std::cout << "Constructed from a pair, t4: "; print(t4);
     // given Allocator my_alloc with a single-argument constructor
     // my_alloc(int); use my_alloc(1) to allocate 5 ints in a vector
     using my_alloc = std::allocator<int>;
     std::vector<int, my_alloc> v { 5, 1, my_alloc{/*1*/} };
     // use my_alloc(2) to allocate 5 ints in a vector in a tuple
     std::tuple<int, std::vector<int, my_alloc>, double> t5{
         std::allocator_arg, my_alloc{/*2*/}, 42, v, -3.14};
     std::cout << "Constructed with allocator, t5: "; print(t5);
 }

Possible output:
 Value-initialized, t1: (0, "", 0)
 Initialized with values, t2: (42, "Test", -3.14)
 Implicitly converted, t3: ('*', "Test", -3)
 Constructed from a pair, t4: (42, 3.14)
 Constructed with allocator, t5: (42, {1,1,1,1,1}, -3.14)
  Defect reports
   The following behavior-changing defect reports were applied retroactively to
   previously published C++ standards.
      DR Applied to Behavior as published Correct behavior
   N4387 C++11 some constructors were explicit, most constructors made
                       preventing useful behavior conditionally-explicit
   LWG 2510 C++11 default constructor was implicit made conditionally-explicit
                       constructor of 1-tuple might
   LWG 3121 C++11 recursively check the constraints; furtherly constrained the
                       allocator_arg_t argument brought constructor
                       ambiguity
                       the uses-allocator constructor
   LWG 3158 C++11 corresponding to made conditionally-explicit
                       default constructor was implicit
   LWG 3211 C++11 whether the default constructor of require to be trivial
                       tuple<> is trivial was unspecified

See also
   operator= assigns the contents of one tuple to another
   (C++11) (public member function)
   make_tuple creates a tuple object of the type defined by the argument types
   (C++11) (function template)
   tie creates a tuple of lvalue references or unpacks a tuple into
   (C++11) individual objects
                    (function template)
   forward_as_tuple creates a tuple of forwarding references
   (C++11) (function template)
   constructor constructs new pair
                    (public member function of std::pair<T1,T2>)