std::variant<Types...>:: variant
|
constexpr
variant
(
)
noexcept
(
/* siehe unten */
)
;
|
(1) | (seit C++17) |
|
constexpr
variant
(
const
variant
&
other
)
;
|
(2) | (seit C++17) |
|
constexpr
variant
(
variant
&&
other
)
noexcept
(
/* siehe unten */
)
;
|
(3) | (seit C++17) |
|
template
<
class
T
>
constexpr variant ( T && t ) noexcept ( /* siehe unten */ ) ; |
(4) | (seit C++17) |
|
template
<
class
T,
class
...
Args
>
|
(5) | (seit C++17) |
|
template
<
class
T,
class
U,
|
(6) | (seit C++17) |
|
template
<
std::
size_t
I,
class
...
Args
>
|
(7) | (seit C++17) |
|
template
<
std::
size_t
I,
class
U,
|
(8) | (seit C++17) |
Konstruiert ein neues
variant
-Objekt.
variant
, der den
wertinitialisierten
Wert der ersten Alternative hält (
index()
ist null).
-
Dieser Konstruktor ist
constexpr
genau dann, wenn die Wertinitialisierung des Alternativtyps
T_0die Anforderungen für eine constexpr-Funktion erfüllen würde. - Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn std:: is_default_constructible_v < T_0 > true ist.
variant
, das dieselbe Alternative wie
other
hält und
direkt-initialisiert
den enthaltenen Wert mit
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
. Andernfalls initialisiert er ein
valueless_by_exception
-Variant.
-
Dieser Konstruktor ist als gelöscht definiert, es sei denn
std::
is_copy_constructible_v
<
T_i
>
ist
true
für alle
T_iin Types... . -
Er ist trivial, falls
std::
is_trivially_copy_constructible_v
<
T_i
>
ist
true
für alle
T_iin Types... .
variant
, das dieselbe Alternative wie
other
hält und
direkt-initialisiert
den enthaltenen Wert mit
std
::
move
(
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
)
. Andernfalls initialisiert es ein
valueless_by_exception
-Variant.
-
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
std::
is_move_constructible_v
<
T_i
>
für alle
T_iin Types... true ist. -
Er ist trivial, wenn
std::
is_trivially_move_constructible_v
<
T_i
>
für alle
T_iin Types... true ist.
variant
, der den alternativen Typ
T_j
enthält, der durch Überladungsauflösung für den Ausdruck
F
(
std::
forward
<
T
>
(
t
)
)
ausgewählt würde, wenn es eine Überladung der imaginären Funktion
F(T_i)
für jedes
T_i
in
Types...
gäbe, außer dass einschränkende Konvertierungen nicht berücksichtigt werden.
Formal:
-
-
Eine Überladung
F
(
T_i
)
wird nur berücksichtigt, wenn die Deklaration
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
für eine erfundene Variable
xgültig ist.
-
Eine Überladung
F
(
T_i
)
wird nur berücksichtigt, wenn die Deklaration
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
für eine erfundene Variable
-
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
- sizeof... ( Types ) > 0 ,
-
std::
decay_t
<
T
>
(bis C++20)
std::
remove_cvref_t
<
T
>
(seit C++20)
weder der gleiche Typ wie
variantist, noch eine Spezialisierung von std::in_place_type_t , noch eine Spezialisierung von std::in_place_index_t , - std:: is_constructible_v < T_j, T > true ist,
- und der Ausdruck F ( std:: forward < T > ( t ) ) (wobei F die oben erwähnte Menge imaginärer Funktionen ist) wohlgeformt ist.
-
Dieser Konstruktor ist ein
constexpr
-Konstruktor, wenn der ausgewählte Konstruktor von
T_jein constexpr-Konstruktor ist.
std::variant<std::string> v("abc"); // OK std::variant<std::string, std::string> w("abc"); // ungültig std::variant<std::string, const char*> x("abc"); // OK, wählt const char* std::variant<std::string, bool> y("abc"); // OK, wählt string; bool ist kein Kandidat std::variant<float, long, double> z = 0; // OK, enthält long // float und double sind keine Kandidaten
variant
mit der angegebenen Alternative
T
und initialisiert den enthaltenen Wert mit den Argumenten
std::
forward
<
Args
>
(
args
)
...
.
-
Wenn der ausgewählte Konstruktor von
Tein constexpr -Konstruktor ist, ist dieser Konstruktor ebenfalls ein constexpr -Konstruktor. -
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
Tgenau einmal in Types... vorkommt und std:: is_constructible_v < T, Args... > true ist.
variant
mit der angegebenen Alternative
T
und initialisiert den enthaltenen Wert mit den Argumenten
il,
std::
forward
<
Args
>
(
args
)
...
.
-
Wenn der ausgewählte Konstruktor von
Tein constexpr -Konstruktor ist, ist dieser Konstruktor ebenfalls ein constexpr -Konstruktor. -
Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn
Tgenau einmal in Types... vorkommt und std:: is_constructible_v < T, initializer_list < U > & , Args... > den Wert true hat.
variant
mit der durch den Index
I
spezifizierten Alternative
T_i
und initialisiert den enthaltenen Wert mit den Argumenten
std::
forward
<
Args
>
(
args
)
...
.
-
Falls der ausgewählte Konstruktor von
T_iein constexpr -Konstruktor ist, ist dieser Konstruktor ebenfalls ein constexpr -Konstruktor. - Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn I < sizeof... ( Types ) und std:: is_constructible_v < T_i, Args... > true ist.
variant
mit der durch den Index
I
spezifizierten Alternative
T_i
und initialisiert den enthaltenen Wert mit den Argumenten
il,
std::
forward
<
Args
>
(
args
)
...
.
-
Wenn der ausgewählte Konstruktor von
T_iein constexpr -Konstruktor ist, dann ist dieser Konstruktor ebenfalls ein constexpr -Konstruktor. - Diese Überladung nimmt nur dann an der Überladungsauflösung teil, wenn I < sizeof... ( Types ) und std:: is_constructible_v < T_i, std:: initializer_list < U > & , Args... > gleich true ist.
Inhaltsverzeichnis |
Parameter
| other | - |
ein weiteres
variant
Objekt, dessen enthaltenen Wert kopiert/verschoben werden soll
|
| t | - | Wert zur Initialisierung des enthaltenen Werts |
| args... | - | Argumente zur Initialisierung des enthaltenen Werts |
| il | - | Initialisierungsliste zur Initialisierung des enthaltenen Werts |
Exceptions
T_i
in
Types...
ausgelöst wird.
T_i
in
Types...
ausgelöst wird.
T_j
ausgelöst wird.
Hinweise
MSVC STL behandelte ursprünglich P0608R3 als Änderung in C++20. Ab VS 2022 17.12 behandelt MSVC STL P0608R3 auch als Defect Report gegen C++17.
Beispiel
#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() { // value-initialisiert erste Alternative std::variant<int, std::string> var0; assert(std::holds_alternative<int>(var0) and var0.index() == 0 and std::get<int>(var0) == 0); // initialisiert erste Alternative mit std::string{"STR"}; std::variant<std::string, int> var1{"STR"}; assert(var1.index() == 0); std::cout << "1) " << std::get<std::string>(var1) << '\n'; // initialisiert zweite Alternative mit int == 42; std::variant<std::string, int> var2{42}; assert(std::holds_alternative<int>(var2)); std::cout << "2) " << std::get<int>(var2) << '\n'; // initialisiert erste Alternative mit 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::get<std::string>(var3) << '\n'; // initialisiert die zweite Alternative mit 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::get<vector_t>(var4) << '\n'; // initialisiert erste Alternative mit 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::get<std::string>(var5) << '\n'; // initialisiert zweite Alternative mit 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::get<vector_t>(var6) << '\n'; }
Ausgabe:
1) STR
2) 42
3) AAAA
4) { 1 2 3 4 5 }
5) ABC
6) { 42 42 42 42 }
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2901 | C++17 |
Allokator-bewusste Konstruktoren bereitgestellt, aber
variant
kann Allokatoren nicht ordnungsgemäß unterstützen
|
Konstruktoren entfernt |
| P0739R0 | C++17 |
Konvertierungskonstruktor-Template interagiert
schlecht mit Klassen-Template-Argumentableitung |
Einschränkung hinzugefügt |
| LWG 3024 | C++17 |
Kopierkonstruktor nimmt nicht an der
Überladungsauflösung teil, wenn ein Mitgliedstyp nicht kopierbar ist |
Stattdessen als gelöscht definiert |
| P0602R4 | C++17 |
Kopier-/Verschiebekonstruktoren können nicht
trivial sein, selbst wenn zugrunde liegende Konstruktoren trivial sind |
Muss Trivialität weitergeben |
| P0608R3 | C++17 |
Konvertierungskonstruktor stellt blind
einen Überladungssatz zusammen, was zu unbeabsichtigten Konvertierungen führt |
Einschränkende und boolesche Konvertierungen nicht berücksichtigt |
| P1957R2 | C++17 |
Konvertierungskonstruktor für
bool
erlaubte keine
implizite Konvertierung |
Zeiger-zu-
bool
Konvertierung ist einschränkend und
Konvertierungskonstruktor hat keine Ausnahme für bool |