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, -
Ti
be thei
th type inTypes
, and -
Ui
be thei
th 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
Ti
is 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
D
be std:: decay < U0 > :: type (until C++20) std:: remove_cvref_t < U0 > (since C++20) ,-
if
sizeof...
(
Types
)
==
1
, then
D
is notstd::tuple
, otherwise, -
if
sizeof...
(
Types
)
==
2
or
sizeof...
(
Types
)
==
3
, then either
D
is not std::allocator_arg_t , orT0
is 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
i
th 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 toT
andUTypes...
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
i
th 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) .
i
th 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 of
tuple<>
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>
)
|