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) |
tuple( const tuple& other ) = default; |
(12) | (since C++11) |
tuple( tuple&& other ) = default; |
(13) | (since C++11) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a ); |
(14) | (since C++11) (constexpr since C++20) (conditionally explicit) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a, const Types&... args ); |
(15) | (since C++11) (constexpr since C++20) (conditionally explicit) |
template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a, UTypes&&... args ); |
(16) | (since C++11) (constexpr since C++20) (conditionally explicit) |
template< class Alloc, class... UTypes > constexpr tuple( std::allocator_arg_t, const Alloc& a, tuple<UTypes...>& other ); |
(17) | (since C++23) (conditionally explicit) |
template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a, const tuple<UTypes...>& other ); |
(18) | (since C++11) (constexpr since C++20) (conditionally explicit) |
template< class Alloc, class... UTypes > tuple( std::allocator_arg_t, const Alloc& a, tuple<UTypes...>&& other ); |
(19) | (since C++11) (constexpr since C++20) (conditionally explicit) |
template< class Alloc, class... UTypes > constexpr tuple( std::allocator_arg_t, const Alloc& a, const tuple<UTypes...>&& other ); |
(20) | (since C++23) (conditionally explicit) |
template< class Alloc, class U1, class U2 > constexpr tuple( std::allocator_arg_t, const Alloc& a, std::pair<U1, U2>& p ); |
(21) | (since C++23) (conditionally explicit) |
template< class Alloc, class U1, class U2 > tuple( std::allocator_arg_t, const Alloc& a, const std::pair<U1, U2>& p ); |
(22) | (since C++11) (constexpr since C++20) (conditionally explicit) |
template< class Alloc, class U1, class U2 > tuple( std::allocator_arg_t, const Alloc& a, std::pair<U1, U2>&& p ); |
(23) | (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, const std::pair<U1, U2>&& p ); |
(24) | (since C++23) (conditionally explicit) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a, const tuple& other ); |
(25) | (since C++11) (constexpr since C++20) |
template< class Alloc > tuple( std::allocator_arg_t, const Alloc& a, tuple&& other ); |
(26) | (since C++11) (constexpr since C++20) |
Constructs a new tuple.
1) Default constructor. Value-initializes all elements, if any. The default constructor is trivial ifsizeof...(Types) == 0
.
- This overload participates in overload resolution only if
std::is_default_constructible<Ti>::value
istrue
for alli
- The constructor is
explicit
if and only ifTi
is not copy-list-initializable from{}
for at least onei
.
- This overload participates in overload resolution only if
sizeof...(Types) >= 1
andstd::is_copy_constructible<Ti>::value
istrue
for alli
. - This constructor is
explicit
if and only ifstd::is_convertible<const Ti&, Ti>::value
isfalse
for at least onei
.
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
istrue
for alli
, and - let
D
bestd::decay<U0>::type
(until C++20)std::remove_cvref_t<U0>
(since C++20),- if
sizeof...(Types) == 1
, thenD
is nottuple
, otherwise, - if
sizeof...(Types) == 2
orsizeof...(Types) == 3
, then eitherD
is notstd::allocator_arg_t
, orT0
isstd::allocator_arg_t
.
- if
-
- The constructor is
explicit
if and only ifstd::is_convertible<Ui, Ti>::value
isfalse
for at least onei
.
|
(since C++23) |
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&>
istrue
for alli
and - either
-
sizeof...(Types) != 1
or - (when
Types...
expands toT
andUTypes...
expands toU
)std::is_convertible_v<tuple<U>&, T>
,std::is_constructible_v<T, tuple<U>&>
, andstd::is_same_v<T, U>
are allfalse
.
-
-
- The constructor is
explicit
if and only ifstd::is_convertible_v<Ui&, Ti>
isfalse
for at least onei
. - This constructor is defined as deleted if the initialization of any element that is a reference would bind it to a temporary object.
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
istrue
for alli
and - either
-
sizeof...(Types) != 1
or - (when
Types...
expands toT
andUTypes...
expands toU
)std::is_convertible<const tuple<U>&, T>::value
,std::is_constructible<T, const tuple<U>&>::value
, andstd::is_same<T, U>::value
are allfalse
.
-
-
- The constructor is
explicit
if and only ifstd::is_convertible<const Ui&, Ti>::value
isfalse
for at least onei
.
|
(since C++23) |
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
istrue
for alli
and - either
-
sizeof...(Types) != 1
or - (when
Types...
expands toT
andUTypes...
expands toU
)std::is_convertible<tuple<U>, T>::value
,std::is_constructible<T, tuple<U>>::value
, andstd::is_same<T, U>::value
are allfalse
.
-
-
- The constructor is
explicit
if and only ifstd::is_convertible<Ui, Ti>::value
isfalse
for at least onei
.
|
(since C++23) |
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>
istrue
for alli
and - either
-
sizeof...(Types) != 1
or - (when
Types...
expands toT
andUTypes...
expands toU
)std::is_convertible_v<const tuple<U>, T>
,std::is_constructible_v<T, const tuple<U>>
, andstd::is_same_v<T, U>
are allfalse
.
-
-
- The constructor is
explicit
if and only ifstd::is_convertible_v<const Ui, Ti>
isfalse
for at least onei
. - This constructor is defined as deleted if the initialization of any element that is a reference would bind it to a temporary object.
p.first
and the second element from
p.second
- This overload participates in overload resolution only if
sizeof...(Types) == 2
andstd::is_constructible_v<T0, U1&>
andstd::is_constructible_v<T1, U2&>
are bothtrue
- The constructor is
explicit
if and only ifstd::is_convertible_v<U1&, T0>
orstd::is_convertible_v<U2&, T1>
isfalse
. - This constructor is defined as deleted if the initialization of any element that is a reference would bind it to a temporary object.
p.first
and the second element from
p.second
- This overload participates in overload resolution only if
sizeof...(Types) == 2
andstd::is_constructible<T0,const U1&>::value
andstd::is_constructible<T1, const U2&>::value
are bothtrue
- The constructor is
explicit
if and only ifstd::is_convertible<const U1&, T0>::value
orstd::is_convertible<const U2&, T1>::value
isfalse
.
|
(since C++23) |
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
andstd::is_constructible<T0, U1>::value
andstd::is_constructible<T1, U2>::value
are bothtrue
- The constructor is
explicit
if and only ifstd::is_convertible<U1, T0>::value
orstd::is_convertible<U2, T1>::value
isfalse
.
|
(since C++23) |
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
andstd::is_constructible_v<T0, const U1>
andstd::is_constructible_v<T1, const U2>
are bothtrue
- The constructor is
explicit
if and only ifstd::is_convertible_v<U1, T0>
orstd::is_convertible_v<U2, T1>
isfalse
. - This constructor is defined as deleted if the initialization of any element that is a reference would bind it to a temporary object.
other
.
- This constructor is
constexpr
if every operation it performs isconstexpr
. For the empty tuplestd::tuple<>
, it isconstexpr
. -
std::is_copy_constructible<Ti>::value
must betrue
for alli
, otherwise the behavior is undefined (until C++20)the program is ill-formed (since C++20).
std::forward<Ui>(std::get<i>(other))
.
- This constructor is
constexpr
if every operation it performs isconstexpr
. For the empty tuplestd::tuple<>
, it isconstexpr
. -
std::is_move_constructible<Ti>::value
must betrue
for alli
, 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
#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, preventing useful behavior | most constructors made conditionally-explicit |
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 |
See also
(C++11)
|
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> ) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/utility/tuple/tuple