std::tuple<Types...>::tuple
| Défini dans l'en-tête <tuple>
|
||
constexpr tuple();
|
(1) | (depuis C++11) (explicite conditionnellement) |
tuple( const Types&... args );
|
(2) | (depuis C++11) (constexpr depuis C++14) (explicite conditionnellement) |
template< class... UTypes >
tuple( UTypes&&... args );
|
(3) | (depuis C++11) (constexpr depuis C++14) (explicite conditionnellement) |
template< class... UTypes >
constexpr tuple( tuple<UTypes...>& other );
|
(4) | (depuis C++23) (explicite conditionnellement) |
template< class... UTypes >
tuple( const tuple<UTypes...>& other );
|
(5) | (depuis C++11) (constexpr depuis C++14) (explicite conditionnellement) |
template< class... UTypes >
tuple( tuple<UTypes...>&& other );
|
(6) | (depuis C++11) (constexpr depuis C++14) (explicite conditionnellement) |
template< class... UTypes >
constexpr tuple( const tuple<UTypes...>&& other );
|
(7) | (depuis C++23) (explicite conditionnellement) |
template< class U1, class U2 >
constexpr tuple( std::pair<U1, U2>& p );
|
(8) | (depuis C++23) (explicite conditionnellement) |
template< class U1, class U2 >
tuple( const std::pair<U1, U2>& p );
|
(9) | (depuis C++11) (constexpr depuis C++14) (explicite conditionnellement) |
template< class U1, class U2 >
tuple( std::pair<U1, U2>&& p );
|
(10) | (depuis C++11) (constexpr depuis C++14) (explicite conditionnellement) |
template< class U1, class U2 >
constexpr tuple( const std::pair<U1, U2>&& p );
|
(11) | (depuis C++23) (explicite conditionnellement) |
template< tuple-like UTuple >
constexpr tuple( UTuple&& u );
|
(12) | (depuis C++23) (explicite conditionnellement) |
tuple( const tuple& other ) = default;
|
(13) | (depuis C++11) |
tuple( tuple&& other ) = default;
|
(14) | (depuis C++11) |
| Constructeurs étendus avec allocateur |
||
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a );
|
(15) | (depuis C++11) (constexpr depuis C++20) (explicite conditionnellement) |
template< class Alloc >
tuple( std::allocator_arg_t, const Alloc& a,
const Types&... args );
|
(16) | (depuis C++11) (constexpr depuis C++20) (explicite conditionnellement) |
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
UTypes&&... args );
|
(17) | (depuis C++11) (constexpr depuis C++20) (explicite conditionnellement) |
template< class Alloc, class... UTypes >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
tuple<UTypes...>& other );
|
(18) | (depuis C++23) (explicite conditionnellement) |
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) (explicite conditionnellement) |
template< class Alloc, class... UTypes >
tuple( std::allocator_arg_t, const Alloc& a,
tuple<UTypes...>&& other );
|
(20) | (depuis C++11) (constexpr depuis C++20) (explicite conditionnellement) |
template< class Alloc, class... UTypes >
constexpr tuple( std::allocator_arg_t, const Alloc& a,
const tuple<UTypes...>&& other );
|
(21) | (depuis C++23) (explicite conditionnellement) |
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) (explicite conditionnellement) |
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) (explicite conditionnellement) |
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) (explicite conditionnellement) |
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) (explicite conditionnellement) |
template< class Alloc, tuple-like UTuple >
constexpr tuple( std::allocator_arg_t, const Alloc& a, UTuple&& u );
|
(26) | (depuis C++23) (explicite conditionnellement) |
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
idans l'intervalle[0,sizeof...(Types))dans l'ordre,Tileième type dansTypes, etUileième type dans un pack de paramètres de modèle nomméUTypes,
où l'indexation est basée sur zéro.
sizeof...(Types) == 0.
- Cette surcharge participe à la résolution de surcharge uniquement si
std::is_default_constructible<Ti>::valueesttruepour tous lesi. - Le constructeur est
explicitsi et seulement siTin'est pas initialisable par liste de copie à partir de{}pour au moins uni.
- Cette surcharge participe à la résolution de surcharge uniquement si
sizeof...(Types) >= 1etstd::is_copy_constructible<Ti>::valueesttruepour tous lesi. - Ce constructeur est
explicitsi et seulement sistd::is_convertible<const Ti&, Ti>::valueestfalsepour au moins uni.
std::forward<UTypes>(args).
- Cette surcharge participe à la résolution de surcharge uniquement si
sizeof...(Types) == sizeof...(UTypes),sizeof...(Types) >= 1,std::is_constructible<Ti, Ui>::valueesttruepour tous lesi, et- soit
Dsoitstd::decay<U0>::type(jusqu'à C++20)std::remove_cvref_t<U0>(depuis C++20),- si
sizeof...(Types) == 1, alorsDn'est passtd::tuple, sinon, - si
sizeof...(Types) == 2ousizeof...(Types) == 3, alors soitDn'est pas std::allocator_arg_t, ouT0est std::allocator_arg_t.
- si
- Le constructeur est
explicitsi et seulement sistd::is_convertible<Ui, Ti>::valueestfalsepour au moins uni.
|
(depuis C++23) |
other.
Formellement, soit FWD(other) soit std::forward<decltype(other)>(other), pour tous les i, initialise le ième élément du tuple avec std::get<i>(FWD(other)).
- Cette surcharge participe à la résolution de surcharge uniquement si
sizeof...(Types) == sizeof...(UTypes),std::is_constructible_v<Ti, decltype(std::get<i>(FWD(other)))>esttruepour tous lesi, et- soit
sizeof...(Types)n'est pas1, ou- (lorsque
Types...se développe enTetUTypes...se développe enU)std::is_convertible_v<decltype(other), T>,std::is_constructible_v<T, decltype(other)>, etstd::is_same_v<T, U>sont tousfalse.
- Ces constructeurs sont
explicitsi et seulement sistd::is_convertible_v<decltype(std::get<i>(FWD(other))), Ti>estfalsepour au moins uni.
|
(depuis C++23) |
p.
Formellement, soit FWD(p) soit 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)).
- Cette surcharge participe à la résolution de surcharge uniquement si
sizeof...(Types) == 2,std::is_constructible_v<T0, decltype(std::get<0>(FWD(p)))>esttrue, etstd::is_constructible_v<T1, decltype(std::get<1>(FWD(p)))>esttrue.
- Le constructeur est
explicitsi et seulement sistd::is_convertible_v<decltype(std::get<0>(FWD(p))), T0>oustd::is_convertible_v<decltype(std::get<1>(FWD(p))), T1>estfalse.
|
(depuis C++23) |
tuple-like constructeur. Construit un tuple dont chaque élément est construit à partir de l'élément correspondant de u.
Formellement, pour tous les i, initialise le ième élément du tuple avec std::get<i>(std::forward<UTuple>(u)).
- Cette surcharge participe à la résolution de surcharge uniquement si
std::same_as<std::remove_cvref_t<UTuple>, std::tuple>estfalse,std::remove_cvref_t<UTuple>n'est pas une spécialisation de std::ranges::subrange,sizeof...(Types)est égal àstd::tuple_size_v<std::remove_cvref_t<UTuple>>,std::is_constructible_v<Ti, decltype(std::get<i>(std::forward<UTuple>(u)))>esttruepour tous lesi, et- soit
sizeof...(Types)n'est pas1, ou- (lorsque
Types...se développe enT)std::is_convertible_v<UTuple, T>etstd::is_constructible_v<T, UTuple>sont tous deuxfalse.
- Ce constructeur est défini comme supprimé si l'initialisation d'un élément qui est une référence le lie à un objet temporaire.
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>::valuedoit êtretruepour tous lesi, sinon le comportement est indéfini(jusqu'à C++20)le programme est mal formé(depuis C++20).
i, initialise le 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>::valuedoit êtretruepour tous lesi, sinon le comportement est indéfini(jusqu'à C++20)cette surcharge ne participe pas à la résolution de surcharge(depuis C++20).
a est passé comme argument supplémentaire au constructeur de chaque élément pour lequel std::uses_allocator<Ui, Alloc>::value est true.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) |
|
(C++11)
|
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>
)
|