std::tuple<Types...>:: tuple
|
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,
|
(16) |
(depuis C++11)
(constexpr depuis C++20) (conditionnellement explicite) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(17) |
(depuis C++11)
(constexpr depuis C++20) (conditionnellement explicite) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(18) |
(depuis C++23)
(conditionnellement explicite) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(19) |
(depuis C++11)
(constexpr depuis C++20) (conditionnellement explicite) |
|
template
<
class
Alloc,
class
...
UTypes
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(20) |
(depuis C++11)
(constexpr depuis C++20) (conditionnellement explicite) |
|
template
<
class
Alloc,
class
...
UTypes
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(21) |
(depuis C++23)
(conditionnellement explicite) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
constexpr
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(22) |
(depuis C++23)
(conditionnellement explicite) |
|
template
<
class
Alloc,
class
U1,
class
U2
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(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,
|
(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,
|
(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,
|
(27) |
(depuis C++11)
(constexpr depuis C++20) |
|
template
<
class
Alloc
>
tuple
(
std::
allocator_arg_t
,
const
Alloc
&
a,
|
(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, -
Tisoit lei-ième type dansTypes, et -
Uisoit lei-ième type dans un paquet de paramètres de template nomméUTypes,
où l'indexation commence à zéro.
- 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
Tin'est pas initialisable par liste de copie depuis { } pour au moins un i .
- 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 .
-
Cette surcharge participe à la résolution de surcharge seulement si
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- sizeof... ( Types ) >= 1 ,
- std:: is_constructible < Ti, Ui > :: value est true pour tous les i , et
-
soit
Ddéfini comme std:: decay < U0 > :: type (jusqu'à C++20) std:: remove_cvref_t < U0 > (depuis C++20) ,-
si
sizeof...
(
Types
)
==
1
, alors
Dn'est passtd::tuple, sinon, -
si
sizeof...
(
Types
)
==
2
ou
sizeof...
(
Types
)
==
3
, alors soit
Dn'est pas std::allocator_arg_t , soitT0est std::allocator_arg_t .
-
si
sizeof...
(
Types
)
==
1
, alors
- Le constructeur est explicit si et seulement si std:: is_convertible < Ui, Ti > :: value est false pour au moins un i .
|
(depuis C++23) |
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
- sizeof... ( Types ) == sizeof... ( UTypes ) ,
- std:: is_constructible_v < Ti, decltype ( std :: get < i > ( FWD ( other ) ) ) > est true pour tout i , et
-
soit
- sizeof... ( Types ) n'est pas 1 , soit
-
(lorsque
Types...se développe enTetUTypes...se développe enU) std:: is_convertible_v < decltype ( other ) , T > , std:: is_constructible_v < T, decltype ( other ) > , et std:: is_same_v < T, U > sont tous false .
- 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 .
|
(since C++23) |
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 ) ) .
-
Cette surcharge participe à la résolution de surcharge seulement si
- sizeof... ( Types ) == 2 ,
- std:: is_constructible_v < T0, decltype ( std :: get < 0 > ( FWD ( p ) ) ) > est true , et
- std:: is_constructible_v < T1, decltype ( std :: get < 1 > ( FWD ( p ) ) ) > est true .
- Le constructeur est explicit si et seulement si std:: is_convertible_v < decltype ( std :: get < 0 > ( FWD ( p ) ) ) , T0 > ou std:: is_convertible_v < decltype ( std :: get < 1 > ( FWD ( p ) ) ) , T1 > est false .
|
(depuis C++23) |
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
)
)
.
-
Cette surcharge participe à la résolution de surcharge seulement si
- std:: same_as < std:: remove_cvref_t < UTuple > , std:: tuple > est false ,
- 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 ) ) ) > est true pour tout i , et
-
soit
- sizeof... ( Types ) n'est pas 1 , soit
-
(lorsque
Types...se développe enT) std:: is_convertible_v < UTuple, T > et std:: is_constructible_v < T, UTuple > sont tous deux false .
- Ce constructeur est défini comme supprimé si l'initialisation d'un élément qui est une référence le lierait à un objet temporaire.
- 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) .
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) .
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) |
|
(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>
)
|