std::tuple<Types...>::tuple
|   Defined in header  <tuple>
  | 
||
|   constexpr tuple();  | 
(1) |  (since C++11)  (conditionally explicit)  | 
|   tuple( const Types&... args );  | 
(2) |  (since C++11)  (constexpr since C++14) (conditionally explicit)  | 
|   template< class... UTypes > tuple( UTypes&&... args );  | 
(3) |  (since C++11)  (constexpr since C++14) (conditionally explicit)  | 
|   template< class... UTypes > constexpr tuple( tuple<UTypes...>& other );  | 
(4) |  (since C++23)  (conditionally explicit)  | 
|   template< class... UTypes > tuple( const tuple<UTypes...>& other );  | 
(5) |  (since C++11)  (constexpr since C++14) (conditionally explicit)  | 
|   template< class... UTypes > tuple( tuple<UTypes...>&& other );  | 
(6) |  (since C++11)  (constexpr since C++14) (conditionally explicit)  | 
|   template< class... UTypes > constexpr tuple( const tuple<UTypes...>&& other );  | 
(7) |  (since C++23)  (conditionally explicit)  | 
|   template< class U1, class U2 > constexpr tuple( std::pair<U1, U2>& p );  | 
(8) |  (since C++23)  (conditionally explicit)  | 
|   template< class U1, class U2 > tuple( const std::pair<U1, U2>& p );  | 
(9) |  (since C++11)  (constexpr since C++14) (conditionally explicit)  | 
|   template< class U1, class U2 > tuple( std::pair<U1, U2>&& p );  | 
(10) |  (since C++11)  (constexpr since C++14) (conditionally explicit)  | 
|   template< class U1, class U2 > constexpr tuple( const std::pair<U1, U2>&& p );  | 
(11) |  (since C++23)  (conditionally explicit)  | 
|   template< tuple-like UTuple > constexpr tuple( UTuple&& u );  | 
(12) |  (since C++23)  (conditionally explicit)  | 
|   tuple( const tuple& other ) = default;  | 
(13) | (since C++11) | 
|   tuple( tuple&& other ) = default;  | 
(14) | (since C++11) | 
|   Allocator-extended constructors  | 
||
|   template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a );  | 
(15) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a,  | 
(16) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a,  | 
(17) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc, class... UTypes > constexpr tuple( std::allocator_arg_t, const Alloc& a,  | 
(18) |  (since C++23)  (conditionally explicit)  | 
|   template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a,  | 
(19) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a,  | 
(20) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc, class... UTypes > constexpr tuple( std::allocator_arg_t, const Alloc& a,  | 
(21) |  (since C++23)  (conditionally explicit)  | 
|   template< class Alloc, class U1, class U2 > constexpr tuple( std::allocator_arg_t, const Alloc& a,  | 
(22) |  (since C++23)  (conditionally explicit)  | 
|   template< class Alloc, class U1, class U2 > tuple( std::allocator_arg_t, const Alloc& a,  | 
(23) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc, class U1, class U2 > tuple( std::allocator_arg_t, const Alloc& a,  | 
(24) |  (since C++11)  (constexpr since C++20) (conditionally explicit)  | 
|   template< class Alloc, class U1, class U2 > constexpr tuple( std::allocator_arg_t, const Alloc& a,  | 
(25) |  (since C++23)  (conditionally explicit)  | 
|   template< class Alloc, tuple-like UTuple > constexpr tuple( std::allocator_arg_t, const Alloc& a, UTuple&& u );  | 
(26) |  (since C++23)  (conditionally explicit)  | 
|   template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a,  | 
(27) |  (since C++11)  (constexpr since C++20)  | 
|   template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a,  | 
(28) |  (since C++11)  (constexpr since C++20)  | 
Constructs a new tuple.
In the descriptions that follow, let
-  i be in the range 
[0,sizeof...(Types))in order, -  
Tibe theith type inTypes, and -  
Uibe theith type in a template parameter pack namedUTypes,
 
where indexing is zero-based.
- 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 
Tiis not copy-list-initializable from {} for at least one i. 
- 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.
 
-  This overload participates in overload resolution only if 
- sizeof...(Types) == sizeof...(UTypes),
 - sizeof...(Types) >= 1,
 - std::is_constructible<Ti, Ui>::value is true for all i, and
 -  let 
Dbe std::decay<U0>::type(until C++20)std::remove_cvref_t<U0>(since C++20),-  if sizeof...(Types) == 1, then 
Dis notstd::tuple, otherwise, -  if sizeof...(Types) == 2 or sizeof...(Types) == 3, then either 
Dis not std::allocator_arg_t, orT0is std::allocator_arg_t. 
 -  if sizeof...(Types) == 1, then 
 
 - The constructor is explicit if and only if std::is_convertible<Ui, Ti>::value is false for at least one i.
 
  | 
(since C++23) | 
Formally, let FWD(other) be std::forward<decltype(other)>(other), for all i, initializes ith element of the tuple with std::get<i>(FWD(other)).
-  This overload participates in overload resolution only if 
- sizeof...(Types) == sizeof...(UTypes),
 - std::is_constructible_v<Ti, decltype(std::get<i>(FWD(other)))> is true for all i, and
 -  either
- sizeof...(Types) is not 1, or
 -  (when 
Types...expands toTandUTypes...expands toU) std::is_convertible_v<decltype(other), T>, std::is_constructible_v<T, decltype(other)>, and std::is_same_v<T, U> are all false. 
 
 - These constructors are explicit if and only if std::is_convertible_v<decltype(std::get<i>(FWD(other))), Ti> is false for at least one i.
 
  | 
(since C++23) | 
Formally, let FWD(p) be std::forward<decltype(p)>(p), initializes the first element with std::get<0>(FWD(p)) and the second element with std::get<1>(FWD(p)).
-  This overload participates in overload resolution only if 
- sizeof...(Types) == 2,
 - std::is_constructible_v<T0, decltype(std::get<0>(FWD(p)))> is true, and
 - std::is_constructible_v<T1, decltype(std::get<1>(FWD(p)))> is true.
 
 - The constructor is explicit if and only if std::is_convertible_v<decltype(std::get<0>(FWD(p))), T0> or std::is_convertible_v<decltype(std::get<1>(FWD(p))), T1> is false.
 
  | 
(since C++23) | 
tuple-like constructor. Constructs a tuple with each element constructed from the corresponding element of u.
Formally, for all i, initializes ith element of the tuple with std::get<i>(std::forward<UTuple>(u)).
-  This overload participates in overload resolution only if 
- std::same_as<std::remove_cvref_t<UTuple>, std::tuple> is false,
 - std::remove_cvref_t<UTuple> is not a specialization of std::ranges::subrange,
 - sizeof...(Types) equals std::tuple_size_v<std::remove_cvref_t<UTuple>>,
 - std::is_constructible_v<Ti, decltype(std::get<i>(std::forward<UTuple>(u)))> is true for all i, and
 -  either
- sizeof...(Types) is not 1, or
 -  (when 
Types...expands toT) std::is_convertible_v<UTuple, T> and std::is_constructible_v<T, UTuple> are both false. 
 
 - This constructor is defined as deleted if the initialization of any element that is a reference would bind it to a temporary object.
 
- 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).
 
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).
 
Parameters
| args | - | values used to initialize each element of the tuple | 
| other | - | the tuple of values used to initialize each element of the tuple | 
| p | - | the pair of values used to initialize both elements of the 2-tuple | 
| u | - |  the tuple-like object of values used to initialize each element of the tuple
 | 
| a | - | the 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
#include <iomanip> #include <iostream> #include <memory> #include <string> #include <string_view> #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(std::string_view message, const std::tuple<Args...>& t) { std::cout << message << " ("; TuplePrinter<decltype(t), sizeof...(Args)>::print(t); std::cout << ")\n"; } // end helper function int main() { std::tuple<int, std::string, double> t1; print("Value-initialized, t1:", t1); std::tuple<int, std::string, double> t2{42, "Test", -3.14}; print("Initialized with values, t2:", t2); std::tuple<char, std::string, int> t3{t2}; print("Implicitly converted, t3:", t3); std::tuple<int, double> t4{std::make_pair(42, 3.14)}; print("Constructed from a pair, t4:", 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}; print("Constructed with allocator, t5:", 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 | 
|---|---|---|---|
| LWG 2510 | C++11 | default constructor was implicit | made conditionally-explicit | 
| LWG 3121 | C++11 | constructor of 1-tuple might recursively check the constraints;allocator_arg_t argument brought ambiguity
 | 
furtherly constrained the constructor  | 
| LWG 3158 | C++11 | the uses-allocator constructor corresponding to default constructor was implicit  | 
made conditionally-explicit | 
| LWG 3211 | C++11 | whether the default constructor oftuple<> is trivial was unspecified
 | 
require to be trivial | 
| LWG 4045 | C++23 | tuple-like constructor may potentially create dangling references
 | 
made defined as deleted | 
| N4387 | C++11 | some constructors were explicit, preventing useful behavior | most constructors made conditionally-explicit  | 
See also
  assigns the contents of one tuple to another (public member function)  | |
|    (C++11)  | 
  creates a tuple object of the type defined by the argument types (function template)  | 
|    (C++11)  | 
  creates a tuple of lvalue references or unpacks a tuple into individual objects  (function template)  | 
|    (C++11)  | 
  creates a tuple of forwarding references (function template)  | 
  constructs new pair (public member function of std::pair<T1,T2>)  |