std::variant
| Definiert in der Header-Datei <variant> |
||
| template< class... Types > class variant; |
(seit C++17) | |
Die Klassenschablone std::variant stellt eine typsichere union dar.
Eine Instanz von variant hält zu jedem Zeitpunkt entweder einen Wert eines ihrer alternativen Typen oder – im Fehlerfall – keinen Wert (dieser Zustand ist schwer zu erreichen, siehe valueless_by_exception).
Wie bei unions wird, wenn ein variant einen Wert eines Objekttyps T enthält, das T-Objekt innerhalb des variant-Objekts verschachtelt.
Ein variant darf keine Referenzen, Arrays oder den Typ void enthalten.
Ein variant darf denselben Typ mehrmals und unterschiedlich cv-qualifizierte Versionen desselben Typs enthalten.
Im Einklang mit dem Verhalten von Unions während der Aggregatinitialisierung enthält ein standardkonstruierter variant einen Wert seiner ersten Alternative, es sei denn, diese Alternative ist nicht standardkonstruierbar (in diesem Fall ist der variant auch nicht standardkonstruierbar). Die Hilfsklasse std::monostate kann verwendet werden, um solche variants standardkonstruierbar zu machen.
Ein Programm, das die Definition von std::variant ohne Schablonenargumente instanziiert, ist fehlerhaft. stattdessen kann std::variant<std::monostate> verwendet werden.
Wenn ein Programm eine explizite oder partielle Spezialisierung von std::variant deklariert, ist das Programm fehlerhaft, ohne Diagnose.
Inhalt |
[bearbeiten] Schablonenparameter
| Typen | - | die Typen, die in diesem variant gespeichert werden können. Alle Typen müssen die Destructible-Anforderungen erfüllen (insbesondere sind Array-Typen und Nicht-Objekttypen nicht erlaubt). |
[bearbeiten] Memberfunktionen
konstruiert das variant-Objekt(public member function) | |
zerstört das variant zusammen mit seinem enthaltenen Wert(public member function) | |
weist einem variant zu(public member function) | |
Observer | |
gibt den nullbasierten Index der vom variant gehaltenen Alternative zurück(public member function) | |
prüft, ob sich der variant im ungültigen Zustand befindet(public member function) | |
Modifizierer | |
konstruiert einen Wert im variant, direkt(public member function) | |
tauscht mit einem anderen variant(public member function) | |
Besuch | |
| (C++26) |
ruft den bereitgestellten Funktor mit dem vom variant gehaltenen Argument auf(public member function) |
[bearbeiten] Nicht-Member-Funktionen
| (C++17) |
ruft den bereitgestellten Funktor mit den von einem oder mehreren variants gehaltenen Argumenten auf(function template) |
| (C++17) |
prüft, ob ein variant derzeit einen gegebenen Typ hält(function template) |
| (C++17) |
liest den Wert des variants anhand des Index oder des Typs (wenn der Typ eindeutig ist), wirft bei Fehler (function template) |
| (C++17) |
erhält einen Zeiger auf den Wert eines aufgerufenen variant anhand des Index oder des Typs (wenn eindeutig), gibt bei Fehler null zurück(function template) |
| (C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20) |
vergleicht variant-Objekte als ihre enthaltenen Werte(function template) |
| (C++17) |
spezialisiert den Algorithmus std::swap (function template) |
[bearbeiten] Hilfsklassen
| (C++17) |
Platzhaltertyp zur Verwendung als erste Alternative in einem variant von nicht standardkonstruierbaren Typen(class) |
| (C++17) |
Ausnahme, die bei ungültigen Zugriffen auf den Wert eines variant geworfen wird(class) |
| (C++17) |
erhält zur Kompilierzeit die Größe der Alternativenliste des variant(class template) (variable template) |
| erhält zur Kompilierzeit den Typ der durch ihren Index angegebenen Alternative (class template) (alias template) | |
| (C++17) |
Hash-Unterstützung für std::variant (Klassentemplate-Spezialisierung) |
[bearbeiten] Hilfsobjekte
| (C++17) |
Index des variant im ungültigen Zustand(constant) |
[bearbeiten] Notizen
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_variant |
201606L |
(C++17) | std::variant: eine typsichere union |
202102L |
(C++23) (DR17) |
std::visit für von std::variant abgeleitete Klassen | |
202106L |
(C++23) (DR20) |
Vollständig constexpr std::variant | |
202306L |
(C++26) | Member visit |
[bearbeiten] Beispiel
#include <cassert> #include <iostream> #include <string> #include <variant> int main() { std::variant<int, float> v, w; v = 42; // v contains int int i = std::get<int>(v); assert(42 == i); // succeeds w = std::get<int>(v); w = std::get<0>(v); // same effect as the previous line w = v; // same effect as the previous line // std::get<double>(v); // error: no double in [int, float] // std::get<3>(v); // error: valid index values are 0 and 1 try { std::get<float>(w); // w contains int, not float: will throw } catch (const std::bad_variant_access& ex) { std::cout << ex.what() << '\n'; } using namespace std::literals; std::variant<std::string> x("abc"); // converting constructors work when unambiguous x = "def"; // converting assignment also works when unambiguous std::variant<std::string, void const*> y("abc"); // casts to void const* when passed a char const* assert(std::holds_alternative<void const*>(y)); // succeeds y = "xyz"s; assert(std::holds_alternative<std::string>(y)); // succeeds }
Mögliche Ausgabe
std::get: wrong index for variant
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2901 | C++17 | Spezialisierung von std::uses_allocator bereitgestellt, aber variant kann Allocatoren nicht ordnungsgemäß unterstützen |
Spezialisierung entfernt |
| LWG 3990 | C++17 | ein Programm könnte eine explizite oder partielle Spezialisierung von std::variant deklarieren |
das Programm ist in diesem Fall fehlerhaft (keine Diagnose erforderlich) |
| LWG 4141 | C++17 | die Anforderung für die Speicherung Allokation war verwirrend |
Das enthaltene Objekt muss innerhalb des variant-Objekts |
[bearbeiten] Siehe auch
| Tag für In-Place-Konstruktion (Tag) | |
| (C++17) |
ein Wrapper, der möglicherweise ein Objekt enthält oder auch nicht (Klassenvorlage) |
| (C++17) |
Objekte, die Instanzen eines beliebigen CopyConstructible-Typs enthalten (Klasse) |