Namespaces
Variants

std:: variant

From cppreference.net
Utilities library
Definiert im Header <variant>
template < class ... Types >
class variant ;
(seit C++17)

Die Klassenvorlage std::variant repräsentiert eine typsichere Union .

Eine Instanz von variant enthält zu jedem gegebenen 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 gilt: Wenn ein Variant einen Wert eines Objekttyps T enthält, ist das T -Objekt innerhalb des variant -Objekts verschachtelt.

Ein Variant darf keine Referenzen, Arrays oder den Typ void enthalten.

Ein Variant darf denselben Typ mehr als einmal halten und unterschiedlich cv-qualifizierte Versionen desselben Typs halten.

In Übereinstimmung mit dem Verhalten von Unions während der Aggregatinitialisierung hält ein standardmäßig konstruierter Variant einen Wert seiner ersten Alternative, es sei denn, diese Alternative ist nicht standardmäßig konstruierbar (in diesem Fall ist der Variant ebenfalls nicht standardmäßig konstruierbar). Die Hilfsklasse std::monostate kann verwendet werden, um solche Variants standardmäßig konstruierbar zu machen.

Ein Programm, das die Definition von std::variant ohne Template-Argumente instanziiert, ist fehlerhaft. std :: variant < std:: monostate > kann stattdessen verwendet werden.

Wenn ein Programm eine explizite oder partielle Spezialisierung von std::variant deklariert, ist das Programm fehlerhaft, keine Diagnose erforderlich.

Inhaltsverzeichnis

Template-Parameter

Typen - die Typen, die in dieser Variante gespeichert werden können. Alle Typen müssen die Destructible Anforderungen erfüllen (insbesondere sind Array-Typen und Nicht-Objekt-Typen nicht erlaubt).

Memberfunktionen

konstruiert das variant -Objekt
(öffentliche Elementfunktion)
zerstört die variant zusammen mit ihrem enthaltenen Wert
(öffentliche Elementfunktion)
weist eine variant zu
(öffentliche Elementfunktion)
Beobachter
gibt den nullbasierten Index der von der variant gehaltenen Alternative zurück
(öffentliche Elementfunktion)
prüft, ob sich die variant im ungültigen Zustand befindet
(öffentliche Elementfunktion)
Modifikatoren
konstruiert einen Wert in der variant , direkt vor Ort
(öffentliche Elementfunktion)
tauscht mit einer anderen variant
(öffentliche Elementfunktion)
Besuchsfunktionen
(C++26)
ruft den bereitgestellten Funktor mit dem von der variant gehaltenen Argument auf
(öffentliche Elementfunktion)

Nicht-Member-Funktionen

(C++17)
ruft den bereitgestellten Funktor mit den Argumenten auf, die von einem oder mehreren variant s gehalten werden
(Funktions-Template)
prüft, ob eine variant derzeit einen gegebenen Typ hält
(Funktions-Template)
liest den Wert der Variante mit gegebenem Index oder Typ (wenn der Typ eindeutig ist), wirft bei Fehler eine Exception
(Funktions-Template)
(C++17)
erhält einen Zeiger auf den Wert einer gezeigten variant mit gegebenem Index oder Typ (wenn eindeutig), gibt bei Fehler null zurück
(Funktions-Template)
(C++17) (C++17) (C++17) (C++17) (C++17) (C++17) (C++20)
vergleicht variant -Objekte anhand ihrer enthaltenen Werte
(Funktions-Template)
spezialisiert den std::swap -Algorithmus
(Funktions-Template)

Hilfsklassen

(C++17)
Platzhaltertyp für die Verwendung als erste Alternative in einem variant von nicht standardkonstruierbaren Typen
(Klasse)
Ausnahme, die bei ungültigen Zugriffen auf den Wert eines variant geworfen wird
(Klasse)
ermittelt die Größe der Alternativenliste eines variant zur Kompilierzeit
(Klassentemplate) (Variablentemplate)
ermittelt den Typ der durch ihren Index spezifizierten Alternative zur Kompilierzeit
(Klassentemplate) (Aliastemplate)
Hash-Unterstützung für std::variant
(Klassentemplate-Spezialisierung)

Hilfsobjekte

Index des variant im ungültigen Zustand
(Konstante)

Hinweise

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

Beispiel

#include <cassert>
#include <iostream>
#include <string>
#include <variant>
int main()
{
    std::variant<int, float> v, w;
    v = 42; // v enthält int
    int i = std::get<int>(v);
    assert(42 == i); // erfolgreich
    w = std::get<int>(v);
    w = std::get<0>(v); // gleiche Wirkung wie die vorherige Zeile
    w = v; // gleiche Wirkung wie die vorherige Zeile
//  std::get<double>(v); // Fehler: kein double in [int, float]
//  std::get<3>(v);      // Fehler: gültige Indexwerte sind 0 und 1
    try
    {
        std::get<float>(w); // w enthält int, nicht float: wird werfen
    }
    catch (const std::bad_variant_access& ex)
    {
        std::cout << ex.what() << '\n';
    }
    using namespace std::literals;
    std::variant<std::string> x("abc");
    // konvertierende Konstruktoren funktionieren, wenn eindeutig
    x = "def"; // konvertierende Zuweisung funktioniert ebenfalls, wenn eindeutig
    std::variant<std::string, void const*> y("abc");
    // wandelt in void const* um, wenn ein char const* übergeben wird
    assert(std::holds_alternative<void const*>(y)); // erfolgreich
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); // erfolgreich
}

Mögliche Ausgabe:

std::get: wrong index for variant

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 Spezialisierung von std::uses_allocator bereitgestellt,
aber variant kann Allokatoren 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 Speicher-
reservierung war verwirrend
das enthaltene Objekt muss
innerhalb des variant -Objekts geschachtelt sein

Siehe auch

In-Place-Konstruktions-Tag
(Tag)
(C++17)
Ein Wrapper, der möglicherweise ein Objekt enthält
(Klassentemplate)
(C++17)
Objekte, die Instanzen eines beliebigen CopyConstructible Typs enthalten
(Klasse)