Namespaces
Variants

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

From cppreference.net
Utilities library
Défini dans l'en-tête <tuple>
constexpr tuple ( ) ;
(1) (depuis C++11)
(conditionnellement explicite)
tuple ( const Types & ... args ) ;
(2) (depuis C++11)
(constexpr depuis C++14)
(conditionnellement explicite)
template < class ... UTypes >
tuple ( UTypes && ... args ) ;
(3) (depuis C++11)
(constexpr depuis C++14)
(conditionnellement explicite)
template < class ... UTypes >
constexpr tuple ( tuple < UTypes... > & other ) ;
(4) (depuis C++23)
(conditionnellement explicite)
template < class ... UTypes >
tuple ( const tuple < UTypes... > & other ) ;
(5) (depuis C++11)
(constexpr depuis C++14)
(conditionnellement explicite)
template < class ... UTypes >
tuple ( tuple < UTypes... > && other ) ;
(6) (depuis C++11)
(constexpr depuis C++14)
(conditionnellement explicite)
template < class ... UTypes >
constexpr tuple ( const tuple < UTypes... > && other ) ;
(7) (depuis C++23)
(conditionnellement explicite)
template < class U1, class U2 >
constexpr tuple ( std:: pair < U1, U2 > & p ) ;
(8) (depuis C++23)
(conditionnellement explicite)
template < class U1, class U2 >
tuple ( const std:: pair < U1, U2 > & p ) ;
(9) (depuis C++11)
(constexpr depuis C++14)
(conditionnellement explicite)
template < class U1, class U2 >
tuple ( std:: pair < U1, U2 > && p ) ;
(10) (depuis C++11)
(constexpr depuis C++14)
(conditionnellement explicite)
template < class U1, class U2 >
constexpr tuple ( const std:: pair < U1, U2 > && p ) ;
(11) (depuis C++23)
(conditionnellement explicite)
template < tuple - like UTuple >
constexpr tuple ( UTuple && u ) ;
(12) (depuis C++23)
(conditionnellement explicite)
tuple ( const tuple & other ) = default ;
(13) (depuis C++11)
tuple ( tuple && other ) = default ;
(14) (depuis C++11)
Constructeurs étendus par allocateur
template < class Alloc >
tuple ( std:: allocator_arg_t , const Alloc & a ) ;
(15) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc >

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

const Types & ... args ) ;
(16) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc, class ... UTypes >

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

UTypes && ... args ) ;
(17) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc, class ... UTypes >

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

tuple < UTypes... > & other ) ;
(18) (depuis C++23)
(conditionnellement explicite)
template < class Alloc, class ... UTypes >

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

const tuple < UTypes... > & other ) ;
(19) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc, class ... UTypes >

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

tuple < UTypes... > && other ) ;
(20) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc, class ... UTypes >

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

const tuple < UTypes... > && other ) ;
(21) (depuis C++23)
(conditionnellement explicite)
template < class Alloc, class U1, class U2 >

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

std:: pair < U1, U2 > & p ) ;
(22) (depuis C++23)
(conditionnellement explicite)
template < class Alloc, class U1, class U2 >

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

const std:: pair < U1, U2 > & p ) ;
(23) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc, class U1, class U2 >

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

std:: pair < U1, U2 > && p ) ;
(24) (depuis C++11)
(constexpr depuis C++20)
(conditionnellement explicite)
template < class Alloc, class U1, class U2 >

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

const std:: pair < U1, U2 > && p ) ;
(25) (depuis C++23)
(conditionnellement explicite)
template < class Alloc, tuple - like UTuple >
constexpr tuple ( std:: allocator_arg_t , const Alloc & a, UTuple && u ) ;
(26) (depuis C++23)
(conditionnellement explicite)
template < class Alloc >

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

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

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

tuple && other ) ;
(28) (depuis C++11)
(constexpr depuis C++20)

Construit un nouveau tuple.

Dans les descriptions qui suivent, soit

  • i soit dans l'intervalle [ 0 , sizeof... ( Types ) ) dans l'ordre,
  • Ti soit le i -ième type dans Types , et
  • Ui soit le i -ième type dans un paquet de paramètres de template nommé UTypes ,

où l'indexation commence à zéro.

1) Constructeur par défaut. Initialise par valeur tous les éléments, s'il y en a. Le constructeur par défaut est trivial si sizeof... ( Types ) == 0 .
  • Cette surcharge participe à la résolution de surcharge seulement si std:: is_default_constructible < Ti > :: value est true pour tout i .
  • Le constructeur est explicit si et seulement si Ti n'est pas initialisable par liste de copie depuis { } pour au moins un i .
2) Constructeur direct. Initialise chaque élément du tuple avec le paramètre correspondant.
  • Cette surcharge participe à la résolution de surcharge seulement si sizeof... ( Types ) >= 1 et std:: is_copy_constructible < Ti > :: value est true pour tous les i .
  • Ce constructeur est explicit si et seulement si std:: is_convertible < const Ti & , Ti > :: value est false pour au moins un i .
3) Constructeur de conversion. Initialise chaque élément du tuple avec la valeur correspondante dans std:: forward < UTypes > ( args ) .
  • Cette surcharge participe à la résolution de surcharge seulement si
  • Le constructeur est explicit si et seulement si std:: is_convertible < Ui, Ti > :: value est false pour au moins un i .
(depuis C++23)
4-7) Constructeur de conversion. Initialise chaque élément du tuple avec l'élément correspondant de other .

Formellement, soit FWD ( other ) représentant std:: forward < decltype ( other ) > ( other ) , pour tout i , initialise le i -ième élément du tuple avec std :: get < i > ( FWD ( other ) ) .

  • Cette surcharge participe à la résolution de surcharge seulement si
  • Ces constructeurs sont explicit si et seulement si std:: is_convertible_v < decltype ( std :: get < i > ( FWD ( other ) ) ) , Ti > est false pour au moins un i .
  • Ces constructeurs sont définis comme supprimés si l'initialisation d'un élément qui est une référence le lierait à un objet temporaire.
(since C++23)
8-11) Constructeur de paire. Construit un tuple à 2 éléments avec chaque élément construit à partir de l'élément correspondant de p .

Formellement, soit FWD ( p ) comme std:: forward < decltype ( p ) > ( p ) , initialise le premier élément avec std :: get < 0 > ( FWD ( p ) ) et le second élément avec std :: get < 1 > ( FWD ( p ) ) .

  • Ces constructeurs sont définis comme supprimés si l'initialisation d'un élément qui est une référence le lierait à un objet temporaire.
(depuis C++23)
12) tuple-like constructeur. Construit un tuple avec chaque élément construit à partir de l'élément correspondant de u .

Formellement, pour tout i , initialise le i -ième élément du tuple avec std :: get < i > ( std:: forward < UTuple > ( u ) ) .

13) Constructeur de copie implicitement défini. Initialise chaque élément du tuple avec l'élément correspondant de other .
  • Ce constructeur est constexpr si chaque opération qu'il effectue est constexpr . Pour le tuple vide std:: tuple <> , il est constexpr .
  • std:: is_copy_constructible < Ti > :: value doit être true pour tout i , sinon le comportement est indéfini (jusqu'à C++20) le programme est mal formé (depuis C++20) .
14) Constructeur de déplacement implicitement défini. Pour chaque i , initialise le i -ième élément du tuple avec std:: forward < Ui > ( std :: get < i > ( other ) ) .
  • Ce constructeur est constexpr si chaque opération qu'il effectue est constexpr . Pour le tuple vide std:: tuple <> , il est constexpr .
  • std:: is_move_constructible < Ti > :: value doit être true pour tout i , sinon le comportement est indéfini (jusqu'à C++20) cette surcharge ne participe pas à la résolution de surcharge (depuis C++20) .
15-28) Identique à (1-14) sauf que chaque élément est créé par construction uses-allocator , c'est-à-dire que l'objet Allocator a est passé comme argument supplémentaire au constructeur de chaque élément pour lequel std:: uses_allocator < Ui, Alloc > :: value est true .

Table des matières

Paramètres

args - valeurs utilisées pour initialiser chaque élément du tuple
other - le tuple de valeurs utilisées pour initialiser chaque élément du tuple
p - la paire de valeurs utilisée pour initialiser les deux éléments du 2-tuple
u - l'objet tuple-like de valeurs utilisées pour initialiser chaque élément du tuple
a - l'allocateur à utiliser dans la construction avec allocateur

Notes

Les constructeurs conditionnellement explicites permettent de construire un tuple dans un contexte d'initialisation par copie en utilisant la syntaxe d'initialisation par liste :

std::tuple<int, int> foo_tuple() 
{
    // return {1, -1};             // Erreur avant N4387
    return std::make_tuple(1, -1); // Fonctionne toujours
}

Notez que si un élément de la liste n'est pas implicitement convertible vers l'élément correspondant du tuple cible, les constructeurs deviennent explicites :

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}); // Erreur : int n'est pas implicitement convertible en duration
launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK

Exemple

#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <vector>
// fonction auxiliaire pour afficher un vecteur vers un flux
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;
}
// fonction d'assistance pour afficher un tuple de n'importe quelle taille
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::obtenir<N - 1>(t));
    }
};
template<class Tuple>
struct TuplePrinter<Tuple, 1>
{
    static void print(const Tuple& t)
    {
        print_single(std::obtenir<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";
}
// fin de la fonction d'assistance
int main()
{
    std::tuple<int, std::string, double> t1;
    print("Initialisé par valeur, t1:", t1);
    std::tuple<int, std::string, double> t2{42, "Test", -3.14};
    print("Initialisé avec des valeurs, t2:", t2);
    std::tuple<char, std::string, int> t3{t2};
    print("Converti implicitement, t3:", t3);
    std::tuple<int, double> t4{std::make_pair(42, 3.14)};
    print("Construit à partir d'une paire, t4:", t4);
    // étant donné Allocator my_alloc avec un constructeur à un seul argument
    // my_alloc(int); utilisez my_alloc(1) pour allouer 5 entiers dans un vecteur
    using my_alloc = std::allocator<int>;
    std::vector<int, my_alloc> v{5, 1, my_alloc{/* 1 */}};
    // utiliser my_alloc(2) pour allouer 5 entiers dans un vecteur dans un tuple
    std::tuple<int, std::vector<int, my_alloc>, double> t5
        {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3.14};
    print("Construit avec allocateur, t5:", t5);
}

Sortie possible :

Initialisé par valeur, t1: (0, "", 0)
Initialisé avec des valeurs, t2: (42, "Test", -3.14)
Conversion implicite, t3: ('*', "Test", -3)
Construit à partir d'une paire, t4: (42, 3.14)
Construit avec un allocateur, t5: (42, {1,1,1,1,1}, -3.14)

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement corrigé
LWG 2510 C++11 le constructeur par défaut était implicite rendu conditionnellement explicite
LWG 3121 C++11 le constructeur de tuple à 1 élément pouvait vérifier récursivement les contraintes ;
allocator_arg_t provoquait une ambiguïté
contraintes renforcées
pour le constructeur
LWG 3158 C++11 le constructeur utilisant l'allocateur correspondant
au constructeur par défaut était implicite
rendu conditionnellement explicite
LWG 3211 C++11 le caractère trivial du constructeur par défaut de
tuple<> n'était pas spécifié
requis d'être trivial
LWG 4045 C++23 tuple-like le constructeur pouvait potentiellement créer des références pendantes défini comme supprimé
N4387 C++11 certains constructeurs étaient explicites, empêchant des comportements utiles la plupart des constructeurs rendus
conditionnellement explicites

Voir aussi

assigne le contenu d'un tuple à un autre
(fonction membre publique)
(C++11)
crée un objet tuple du type défini par les types d'arguments
(modèle de fonction)
(C++11)
crée un tuple de références lvalue ou décompose un tuple en objets individuels
(modèle de fonction)
crée un tuple de références de transfert
(modèle de fonction)
construit un nouveau pair
(fonction membre publique de std::pair<T1,T2> )