std::variant<Types...>:: variant
|
constexpr
variant
(
)
noexcept
(
/* voir ci-dessous */
)
;
|
(1) | (depuis C++17) |
|
constexpr
variant
(
const
variant
&
other
)
;
|
(2) | (depuis C++17) |
|
constexpr
variant
(
variant
&&
other
)
noexcept
(
/* voir ci-dessous */
)
;
|
(3) | (depuis C++17) |
|
template
<
class
T
>
constexpr variant ( T && t ) noexcept ( /* voir ci-dessous */ ) ; |
(4) | (depuis C++17) |
|
template
<
class
T,
class
...
Args
>
|
(5) | (depuis C++17) |
|
template
<
class
T,
class
U,
|
(6) | (depuis C++17) |
|
template
<
std::
size_t
I,
class
...
Args
>
|
(7) | (depuis C++17) |
|
template
<
std::
size_t
I,
class
U,
|
(8) | (depuis C++17) |
Construit un nouvel objet
variant
.
variant
contenant la valeur
initialisée par défaut
de la première alternative (
index()
est zéro).
-
Ce constructeur est
constexpr
si et seulement si l'initialisation par défaut du type alternatif
T_0satisfait aux exigences d'une fonction constexpr . - Cette surcharge participe à la résolution de surcharge seulement si std:: is_default_constructible_v < T_0 > est true .
variant
contenant la même alternative que
other
et
initialise directement
la valeur contenue avec
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
. Sinon, initialise un variant
valueless_by_exception
.
-
Ce constructeur est défini comme supprimé sauf si
std::
is_copy_constructible_v
<
T_i
>
est
true
pour tous les
T_idans Types... . -
Il est trivial si
std::
is_trivially_copy_constructible_v
<
T_i
>
est
true
pour tous les
T_idans Types... .
variant
contenant la même alternative que
other
et
initialise directement
la valeur contenue avec
std
::
move
(
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
)
. Sinon, initialise un variant
valueless_by_exception
.
-
Cette surcharge participe à la résolution de surcharge seulement si
std::
is_move_constructible_v
<
T_i
>
est
true
pour tous les
T_idans Types... . -
Il est trivial si
std::
is_trivially_move_constructible_v
<
T_i
>
est
true
pour tous les
T_idans Types... .
variant
contenant le type alternatif
T_j
qui serait sélectionné par la résolution de surcharge pour l'expression
F
(
std::
forward
<
T
>
(
t
)
)
s'il existait une surcharge de la fonction imaginaire
F(T_i)
pour chaque
T_i
dans
Types...
, sauf que les conversions rétrécissantes ne sont pas considérées.
Formellement :
-
-
Une surcharge
F
(
T_i
)
n'est considérée que si la déclaration
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
est valide pour une variable inventée
x.
-
Une surcharge
F
(
T_i
)
n'est considérée que si la déclaration
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
est valide pour une variable inventée
-
Cette surcharge participe à la résolution de surcharge seulement si
- sizeof... ( Types ) > 0 ,
-
std::
decay_t
<
T
>
(jusqu'à C++20)
std::
remove_cvref_t
<
T
>
(depuis C++20)
n'est ni le même type que
variant, ni une spécialisation de std::in_place_type_t , ni une spécialisation de std::in_place_index_t , - std:: is_constructible_v < T_j, T > est true ,
- et l'expression F ( std:: forward < T > ( t ) ) (avec F étant l'ensemble mentionné ci-dessus de fonctions imaginaires) est bien formée.
-
Ce constructeur est un constructeur
constexpr
si le constructeur sélectionné de
T_jest un constructeur constexpr.
std::variant<std::string> v("abc"); // OK std::variant<std::string, std::string> w("abc"); // invalide std::variant<std::string, const char*> x("abc"); // OK, choisit const char* std::variant<std::string, bool> y("abc"); // OK, choisit string; bool n'est pas candidat std::variant<float, long, double> z = 0; // OK, contient long // float et double ne sont pas candidats
variant
avec l'alternative spécifiée
T
et initialise la valeur contenue avec les arguments
std::
forward
<
Args
>
(
args
)
...
.
-
Si le constructeur sélectionné de
Test un constructeur constexpr , ce constructeur est également un constructeur constexpr . -
Cette surcharge participe à la résolution de surcharge seulement s'il y a exactement une occurrence de
Tdans Types... et si std:: is_constructible_v < T, Args... > est true .
variant
avec l'alternative spécifiée
T
et initialise la valeur contenue avec les arguments
il,
std::
forward
<
Args
>
(
args
)
...
.
-
Si le constructeur sélectionné de
Test un constructeur constexpr , ce constructeur est également un constructeur constexpr . -
Cette surcharge participe à la résolution de surcharge seulement si
Tapparaît exactement une fois dans Types... et si std:: is_constructible_v < T, initializer_list < U > & , Args... > est true .
variant
avec l'alternative
T_i
spécifiée par l'index
I
et initialise la valeur contenue avec les arguments
std::
forward
<
Args
>
(
args
)
...
.
-
Si le constructeur sélectionné de
T_iest un constructeur constexpr , ce constructeur est également un constructeur constexpr . - Cette surcharge participe à la résolution de surcharge seulement si I < sizeof... ( Types ) et std:: is_constructible_v < T_i, Args... > est true .
variant
avec l'alternative
T_i
spécifiée par l'index
I
et initialise la valeur contenue avec les arguments
il,
std::
forward
<
Args
>
(
args
)
...
.
-
Si le constructeur sélectionné de
T_iest un constructeur constexpr , ce constructeur est également un constructeur constexpr . - Cette surcharge participe à la résolution de surcharge seulement si I < sizeof... ( Types ) et si std:: is_constructible_v < T_i, std:: initializer_list < U > & , Args... > est true .
Table des matières |
Paramètres
| other | - |
autre objet
variant
dont la valeur contenue doit être copiée/déplacée
|
| t | - | valeur pour initialiser la valeur contenue |
| args... | - | arguments pour initialiser la valeur contenue |
| il | - | liste d'initialisation pour initialiser la valeur contenue |
Exceptions
T_i
dans
Types...
.
T_i
dans
Types...
.
T_j
.
Notes
La bibliothèque STL de MSVC a initialement traité P0608R3 comme un changement pour le C++20. À partir de VS 2022 17.12, la bibliothèque STL de MSVC traite également P0608R3 comme un rapport de défaut contre le C++17.
Exemple
#include <cassert> #include <iostream> #include <string> #include <variant> #include <vector> using vector_t = std::vector<int>; auto& operator<<(auto& out, const vector_t& v) { out << "{ "; for (int e : v) out << e << ' '; return out << '}'; } int main() { // initialise la première alternative par valeur std::variant<int, std::string> var0; assert(std::holds_alternative<int>(var0) and var0.index() == 0 and std::obtenir<int>(var0) == 0); // initialise la première alternative avec std::string{"STR"}; std::variant<std::string, int> var1{"STR"}; assert(var1.index() == 0); std::cout << "1) " << std::obtenir<std::string>(var1) << '\n'; // initialise la seconde alternative avec int == 42; std::variant<std::string, int> var2{42}; assert(std::holds_alternative<int>(var2)); std::cout << "2) " << std::obtenir<int>(var2) << '\n'; // initialise la première alternative avec std::string{4, 'A'}; std::variant<std::string, vector_t, float> var3 { std::in_place_type<std::string>, 4, 'A' }; assert(var3.index() == 0); std::cout << "3) " << std::obtenir<std::string>(var3) << '\n'; // initialise la seconde alternative avec std::vector{1,2,3,4,5}; std::variant<std::string, vector_t, char> var4 { std::in_place_type<vector_t>, {1, 2, 3, 4, 5} }; assert(var4.index() == 1); std::cout << "4) " << std::obtenir<vector_t>(var4) << '\n'; // initialise la première alternative avec std::string{"ABCDE", 3}; std::variant<std::string, vector_t, bool> var5 {std::in_place_index<0>, "ABCDE", 3}; assert(var5.index() == 0); std::cout << "5) " << std::obtenir<std::string>(var5) << '\n'; // initialise la seconde alternative avec std::vector(4, 42); std::variant<std::string, vector_t, char> var6 {std::in_place_index<1>, 4, 42}; assert(std::holds_alternative<vector_t>(var6)); std::cout << "6) " << std::obtenir<vector_t>(var6) << '\n'; }
Sortie :
1) STR
2) 42
3) AAAA
4) { 1 2 3 4 5 }
5) ABC
6) { 42 42 42 42 }
` a été conservé tel quel car il s'agit de code/de données qui ne doivent pas être traduits selon les instructions. Seul le texte environnant (s'il y en avait) aurait été traduit en français.
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 2901 | C++17 |
constructeurs sensibles à l'allocateur fournis mais
variant
ne peut pas supporter correctement les allocateurs
|
constructeurs supprimés |
| P0739R0 | C++17 |
le constructeur de conversion template interagit
mal avec la déduction d'arguments de template de classe |
contrainte ajoutée |
| LWG 3024 | C++17 |
le constructeur de copie ne participe pas à la
résolution de surcharge si un type membre n'est pas copiable |
défini comme supprimé à la place |
| P0602R4 | C++17 |
les constructeurs de copie/déplacement peuvent ne pas être
triviaux même si les constructeurs sous-jacents sont triviaux |
requis pour propager la trivialité |
| P0608R3 | C++17 |
le constructeur de conversion assemble aveuglément
un ensemble de surcharge, conduisant à des conversions non intentionnelles |
les conversions de rétrécissement et booléennes ne sont pas considérées |
| P1957R2 | C++17 |
le constructeur de conversion pour
bool
ne permettait pas
la conversion implicite |
La conversion de pointeur vers
bool
est un rétrécissement et
le constructeur de conversion n'a pas d'exception pour bool |