|
|
Member functions | ||||
tuple::tuple | ||||
Non-member functions | ||||
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20) | ||||
Helper concepts | ||||
(C++23) | ||||
Helper classes | ||||
(C++23) | ||||
(C++23) | ||||
Deduction guides(C++17) |
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(conststd::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(conststd::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
[
0,
sizeof...(Types))
in order,Ti
be thei
th type inTypes
, andUi
be thei
th type in a template parameter pack namedUTypes
,where indexing is zero-based.
Ti
is not copy-list-initializable from{} for at least onei.D
bestd::decay<U0>::type(until C++20)std::remove_cvref_t<U0>(since C++20),D
is notstd::tuple
, otherwise,D
is notstd::allocator_arg_t, orT0
isstd::allocator_arg_t.
| (since C++23) |
Formally, letFWD(other) bestd::forward<decltype(other)>(other), for alli, initializesi
th element of the tuple withstd::get<i>(FWD(other)).
Types...
expands toT
andUTypes...
expands toU
)std::is_convertible_v<decltype(other), T>,std::is_constructible_v<T, decltype(other)>, andstd::is_same_v<T, U> are allfalse.
| (since C++23) |
Formally, letFWD(p) bestd::forward<decltype(p)>(p), initializes the first element withstd::get<0>(FWD(p)) and the second element withstd::get<1>(FWD(p)).
| (since C++23) |
tuple-like
constructor. Constructs a tuple with each element constructed from the corresponding element ofu.Formally, for alli, initializesi
th element of the tuple withstd::get<i>(std::forward<UTuple>(u)).
Types...
expands toT
)std::is_convertible_v<UTuple, T> andstd::is_constructible_v<T, UTuple> are bothfalse.i
th element of the tuple withstd::forward<Ui>(std::get<i>(other)).Contents |
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 | - | thetuple-like object of values used to initialize each element of the tuple |
a | - | the allocator to use in uses-allocator construction |
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 N4387returnstd::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:
usingnamespace std::chrono;void launch_rocket_at(std::tuple<hours, minutes, seconds>); launch_rocket_at({hours(1), minutes(2), seconds(3)});// OKlaunch_rocket_at({1,2,3});// Error: int is not implicitly convertible to durationlaunch_rocket_at(std::tuple<hours, minutes, seconds>{1,2,3});// OK
#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 streamtemplate<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(Tconst& v){ifconstexpr(std::is_same_v<T,std::decay_t<std::string>>)std::cout<<std::quoted(v);elseifconstexpr(std::is_same_v<std::decay_t<T>,char>)std::cout<<"'"<< v<<"'";elsestd::cout<< v;} // helper function to print a tuple of any sizetemplate<class Tuple,std::size_t N>struct TuplePrinter{staticvoid 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>{staticvoid print(const Tuple& t){ print_single(std::get<0>(t));}}; template<class...Args>void print(std::string_view message,conststd::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 vectorusing 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 tuplestd::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)
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 |
assigns the contents of onetuple to another(public member function)[edit] | |
(C++11) | creates atuple object of the type defined by the argument types(function template)[edit] |
(C++11) | creates atuple of lvalue references or unpacks a tuple into individual objects (function template)[edit] |
(C++11) | creates atuple offorwarding references(function template)[edit] |
constructs newpair (public member function of std::pair<T1,T2> )[edit] |