std::tuple<Types...>:: tuple
|
Definido en el encabezado
<tuple>
|
||
|
constexpr
tuple
(
)
;
|
(1) |
(desde C++11)
(condicionalmente explícito) |
|
tuple
(
const
Types
&
...
args
)
;
|
(2) |
(desde C++11)
(constexpr desde C++14) (condicionalmente explícito) |
|
template
<
class
...
UTypes
>
tuple ( UTypes && ... args ) ; |
(3) |
(desde C++11)
(constexpr desde C++14) (explícito condicionalmente) |
|
template
<
class
...
UTypes
>
constexpr tuple ( tuple < UTypes... > & other ) ; |
(4) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
...
UTypes
>
tuple ( const tuple < UTypes... > & other ) ; |
(5) |
(desde C++11)
(constexpr desde C++14) (condicionalmente explícito) |
|
template
<
class
...
UTypes
>
tuple ( tuple < UTypes... > && other ) ; |
(6) |
(desde C++11)
(constexpr desde C++14) (explícito condicionalmente) |
|
template
<
class
...
UTypes
>
constexpr tuple ( const tuple < UTypes... > && other ) ; |
(7) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
U1,
class
U2
>
constexpr tuple ( std:: pair < U1, U2 > & p ) ; |
(8) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
U1,
class
U2
>
tuple ( const std:: pair < U1, U2 > & p ) ; |
(9) |
(desde C++11)
(constexpr desde C++14) (condicionalmente explícito) |
|
template
<
class
U1,
class
U2
>
tuple ( std:: pair < U1, U2 > && p ) ; |
(10) |
(desde C++11)
(constexpr desde C++14) (condicionalmente explícito) |
|
template
<
class
U1,
class
U2
>
constexpr tuple ( const std:: pair < U1, U2 > && p ) ; |
(11) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
tuple
-
like UTuple
>
constexpr tuple ( UTuple && u ) ; |
(12) |
(desde C++23)
(condicionalmente explícito) |
|
tuple
(
const
tuple
&
other
)
=
default
;
|
(13) | (desde C++11) |
|
tuple
(
tuple
&&
other
)
=
default
;
|
(14) | (desde C++11) |
|
Constructores extendidos con asignador
|
||
|
template
<
class
Alloc
>
tuple ( std:: allocator_arg_t , const Alloc & a ) ; |
(15) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(16) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(17) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(18) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(19) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(20) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(21) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(22) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(23) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(24) |
(desde C++11)
(constexpr desde C++20) (condicionalmente explícito) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(25) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
Alloc, tuple
-
like UTuple
>
constexpr tuple ( std:: allocator_arg_t , const Alloc & a, UTuple && u ) ; |
(26) |
(desde C++23)
(condicionalmente explícito) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(27) |
(desde C++11)
(constexpr desde C++20) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(28) |
(desde C++11)
(constexpr desde C++20) |
Construye una nueva tupla.
En las descripciones que siguen, sea
-
i
esté en el rango
[ 0 ,sizeof... ( Types ))en orden, -
Tisea eliésimo tipo enTypes, y -
Uisea eliésimo tipo en un paquete de parámetros de plantilla llamadoUTypes,
donde la indexación es de base cero.
- Esta sobrecarga participa en la resolución de sobrecarga solo si std:: is_default_constructible < Ti > :: value es true para todo i .
-
El constructor es
explicit
si y solo si
Tino es inicializable por lista de copia desde { } para al menos un i .
- Esta sobrecarga participa en la resolución de sobrecarga solo si sizeof... ( Types ) >= 1 y std:: is_copy_constructible < Ti > :: value es true para todo i .
- Este constructor es explicit si y solo si std:: is_convertible < const Ti & , Ti > :: value es false para al menos un i .
-
Esta sobrecarga participa en la resolución de sobrecarga solo si
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- sizeof... ( Types ) >= 1 ,
- std:: is_constructible < Ti, Ui > :: value es true para todo i , y
-
sea
Dcomo std:: decay < U0 > :: type (hasta C++20) std:: remove_cvref_t < U0 > (desde C++20) ,-
si
sizeof...
(
Types
)
==
1
, entonces
Dno esstd::tuple, de lo contrario, -
si
sizeof...
(
Types
)
==
2
o
sizeof...
(
Types
)
==
3
, entonces
Dno es std::allocator_arg_t , oT0es std::allocator_arg_t .
-
si
sizeof...
(
Types
)
==
1
, entonces
- El constructor es explicit si y solo si std:: is_convertible < Ui, Ti > :: value es false para al menos un i .
|
(desde C++23) |
Formalmente, sea
FWD
(
other
)
como
std::
forward
<
decltype
(
other
)
>
(
other
)
, para todo
i
, inicializa el elemento
i
-ésimo del tuple con
std
::
get
<
i
>
(
FWD
(
other
)
)
.
-
Esta sobrecarga participa en la resolución de sobrecarga solo si
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- std:: is_constructible_v < Ti, decltype ( std :: get < i > ( FWD ( other ) ) ) > es true para todo i , y
-
ya sea
- sizeof... ( Types ) no es 1 , o
-
(cuando
Types...se expande aTyUTypes...se expande aU) std:: is_convertible_v < decltype ( other ) , T > , std:: is_constructible_v < T, decltype ( other ) > , y std:: is_same_v < T, U > son todos false .
- Estos constructores son explicit si y solo si std:: is_convertible_v < decltype ( std :: get < i > ( FWD ( other ) ) ) , Ti > es false para al menos un i .
|
(desde C++23) |
Formalmente, sea FWD ( p ) igual a std:: forward < decltype ( p ) > ( p ) , inicializa el primer elemento con std :: get < 0 > ( FWD ( p ) ) y el segundo elemento con std :: get < 1 > ( FWD ( p ) ) .
-
Esta sobrecarga participa en la resolución de sobrecarga solo si
- sizeof... ( Types ) == 2 ,
- std:: is_constructible_v < T0, decltype ( std :: get < 0 > ( FWD ( p ) ) ) > es true , y
- std:: is_constructible_v < T1, decltype ( std :: get < 1 > ( FWD ( p ) ) ) > es true .
- El constructor es explicit si y solo si std:: is_convertible_v < decltype ( std :: get < 0 > ( FWD ( p ) ) ) , T0 > o std:: is_convertible_v < decltype ( std :: get < 1 > ( FWD ( p ) ) ) , T1 > es false .
|
(desde C++23) |
tuple-like
constructor. Construye una tupla con cada elemento construido a partir del elemento correspondiente de
u
.
Formalmente, para todo
i
, inicializa el
i
-ésimo elemento de la tupla con
std
::
get
<
i
>
(
std::
forward
<
UTuple
>
(
u
)
)
.
-
Esta sobrecarga participa en la resolución de sobrecarga solo si
- std:: same_as < std:: remove_cvref_t < UTuple > , std:: tuple > es false ,
- std:: remove_cvref_t < UTuple > no es una especialización de std::ranges::subrange ,
- sizeof... ( Types ) es igual a std:: tuple_size_v < std:: remove_cvref_t < UTuple >> ,
- std:: is_constructible_v < Ti, decltype ( std :: get < i > ( std:: forward < UTuple > ( u ) ) ) > es true para todo i , y
-
ya sea que
- sizeof... ( Types ) no sea 1 , o
-
(cuando
Types...se expande aT) std:: is_convertible_v < UTuple, T > y std:: is_constructible_v < T, UTuple > sean ambos false .
- Este constructor se define como eliminado si la inicialización de cualquier elemento que sea una referencia lo vincularía a un objeto temporal.
- Este constructor es constexpr si cada operación que realiza es constexpr . Para la tupla vacía std:: tuple <> , es constexpr .
- std:: is_copy_constructible < Ti > :: value debe ser true para todo i , de lo contrario el comportamiento es indefinido (hasta C++20) el programa está mal formado (desde C++20) .
i
-ésimo elemento de la tupla con
std::
forward
<
Ui
>
(
std
::
get
<
i
>
(
other
)
)
.
- Este constructor es constexpr si cada operación que realiza es constexpr . Para la tupla vacía std:: tuple <> , es constexpr .
- std:: is_move_constructible < Ti > :: value debe ser true para todo i , de lo contrario el comportamiento es indefinido (hasta C++20) esta sobrecarga no participa en la resolución de sobrecarga (desde C++20) .
Contenidos |
Parámetros
| args | - | valores utilizados para inicializar cada elemento de la tupla |
| other | - | la tupla de valores utilizados para inicializar cada elemento de la tupla |
| p | - | el par de valores utilizados para inicializar ambos elementos de la 2-tupla |
| u | - |
el
tuple-like
objeto de valores utilizados para inicializar cada elemento de la tupla
|
| a | - | el asignador a utilizar en la construcción uses-allocator |
Notas
Los constructores condicionalmente explícitos hacen posible construir una tupla en contexto de inicialización por copia usando sintaxis de inicialización de lista:
std::tuple<int, int> foo_tuple() { // return {1, -1}; // Error antes de N4387 return std::make_tuple(1, -1); // Siempre funciona }
Tenga en cuenta que si algún elemento de la lista no es convertible implícitamente al elemento correspondiente de la tupla destino, los constructores se vuelven explícitos:
using namespace std::chrono; void launch_rocket_at(std::tuple<hours, minutes, seconds>); launch_rocket_at({hours(1), minutes(2), seconds(3)}); // CORRECTO launch_rocket_at({1, 2, 3}); // Error: int no es convertible implícitamente a duration launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // CORRECTO
Ejemplo
#include <iomanip> #include <iostream> #include <memory> #include <string> #include <string_view> #include <tuple> #include <type_traits> #include <vector> // función auxiliar para imprimir un vector a un flujo 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; } // función auxiliar para imprimir una tupla de cualquier tamaño template<class Tuple, std::size_t N> struct TuplePrinter { static void print(const Tuple& t) { TuplePrinter<Tuple, N - 1>::imprimir(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)>::imprimir(t); std::cout << ")\n"; } // fin función auxiliar int main() { std::tuple<int, std::string, double> t1; print("Inicializado con valor, t1:", t1); std::tuple<int, std::string, double> t2{42, "Prueba", -3.14}; print("Inicializado con valores, t2:", t2); std::tuple<char, std::string, int> t3{t2}; print("Convertido implícitamente, t3:", t3); std::tuple<int, double> t4{std::make_pair(42, 3.14)}; print("Construido a partir de un par, t4:", t4); // dado Allocator my_alloc con un constructor de un solo argumento // 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 */}}; // usar my_alloc(2) para asignar 5 enteros en un vector en una tupla std::tuple<int, std::vector<int, my_alloc>, double> t5 {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3.14}; print("Construido con asignador, t5:", t5); }
Salida posible:
Inicializado por valor, t1: (0, "", 0)
Inicializado con valores, t2: (42, "Test", -3.14)
Conversión implícita, t3: ('*', "Test", -3)
Construido desde un par, t4: (42, 3.14)
Construido con asignador, t5: (42, {1,1,1,1,1}, -3.14)
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 2510 | C++11 | el constructor por defecto era implícito | hecho condicionalmente-explícito |
| LWG 3121 | C++11 |
el constructor de tupla de 1 elemento podría verificar recursivamente las restricciones;
allocator_arg_t
argumento generaba ambigüedad
|
restringido adicionalmente
el constructor |
| LWG 3158 | C++11 |
el constructor uses-allocator correspondiente
al constructor por defecto era implícito |
hecho condicionalmente-explícito |
| LWG 3211 | C++11 |
si el constructor por defecto de
tuple<>
era trivial no estaba especificado
|
requerido ser trivial |
| LWG 4045 | C++23 |
tuple-like
constructor podría potencialmente crear referencias colgantes
|
definido como eliminado |
| N4387 | C++11 | algunos constructores eran explícitos, impidiendo comportamientos útiles |
la mayoría de constructores hechos
condicionalmente-explícitos |
Véase también
asigna el contenido de un
tuple
a otro
(función miembro pública) |
|
|
(C++11)
|
crea un objeto
tuple
del tipo definido por los tipos de argumento
(plantilla de función) |
|
(C++11)
|
crea un
tuple
de referencias a lvalue o desempaqueta un tuple en objetos individuales
(plantilla de función) |
|
(C++11)
|
crea un
tuple
de
forwarding references
(plantilla de función) |
construye un nuevo
pair
(función miembro pública de
std::pair<T1,T2>
)
|