Namespaces
Variants

std::tuple<Types...>:: tuple

From cppreference.net
Utilities library
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,

const Types & ... args ) ;
(16) (desde C++11)
(constexpr desde C++20)
(condicionalmente explícito)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

UTypes && ... args ) ;
(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,

tuple < UTypes... > & other ) ;
(18) (desde C++23)
(condicionalmente explícito)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

const tuple < UTypes... > & other ) ;
(19) (desde C++11)
(constexpr desde C++20)
(condicionalmente explícito)
template < class Alloc, class ... UTypes >

tuple ( std:: allocator_arg_t , const Alloc & a,

tuple < UTypes... > && other ) ;
(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,

const tuple < UTypes... > && other ) ;
(21) (desde C++23)
(condicionalmente explícito)
template < class Alloc, class U1, class U2 >

constexpr tuple ( std:: allocator_arg_t , const Alloc & a,

std:: pair < U1, U2 > & p ) ;
(22) (desde C++23)
(condicionalmente explícito)
template < class Alloc, class U1, class U2 >

tuple ( std:: allocator_arg_t , const Alloc & a,

const std:: pair < U1, U2 > & p ) ;
(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,

std:: pair < U1, U2 > && p ) ;
(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,

const std:: pair < U1, U2 > && p ) ;
(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,

const tuple & other ) ;
(27) (desde C++11)
(constexpr desde C++20)
template < class Alloc >

tuple ( std:: allocator_arg_t , const Alloc & a,

tuple && other ) ;
(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,
  • Ti sea el i ésimo tipo en Types , y
  • Ui sea el i ésimo tipo en un paquete de parámetros de plantilla llamado UTypes ,

donde la indexación es de base cero.

1) Constructor por defecto. Inicializa por valor todos los elementos, si los hay. El constructor por defecto es trivial si sizeof... ( Types ) == 0 .
  • 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 Ti no es inicializable por lista de copia desde { } para al menos un i .
2) Constructor directo. Inicializa cada elemento de la tupla con el parámetro correspondiente.
  • 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 .
3) Constructor de conversión. Inicializa cada elemento de la tupla con el valor correspondiente en std:: forward < UTypes > ( args ) .
(desde C++23)
4-7) Constructor de conversión. Inicializa cada elemento del tuple con el elemento correspondiente de other .

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
  • 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 .
  • Estos constructores se definen como eliminados si la inicialización de cualquier elemento que sea una referencia lo enlazaría a un objeto temporal.
(desde C++23)
8-11) Constructor de par. Construye una tupla de 2 elementos con cada elemento construido a partir del elemento correspondiente de p .

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 ) ) .

  • Estos constructores se definen como eliminados si la inicialización de cualquier elemento que sea una referencia lo vincularía a un objeto temporal.
(desde C++23)
12) 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 ) ) .

13) Constructor de copia definido implícitamente. Inicializa cada elemento de la tupla con el elemento correspondiente de other .
  • 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) .
14) Constructor de movimiento definido implícitamente. Para todo i , inicializa el 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) .
15-28) Idéntico a (1-14) excepto que cada elemento se crea mediante construcción uses-allocator , es decir, el objeto Allocator a se pasa como argumento adicional al constructor de cada elemento para el cual std:: uses_allocator < Ui, Alloc > :: value es true .

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)
crea un tuple de forwarding references
(plantilla de función)
construye un nuevo pair
(función miembro pública de std::pair<T1,T2> )