std::variant<Types...>:: valueless_by_exception
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Observers | ||||
|
variant::valueless_by_exception
|
||||
| Modifiers | ||||
| Visitation | ||||
|
(C++26)
|
||||
| Non-member functions | ||||
| Helper classes | ||||
| Helper objects | ||||
|
constexpr
bool
valueless_by_exception
(
)
const
noexcept
;
|
(seit C++17) | |
Gibt false genau dann zurück, wenn der Variant keinen Wert enthält.
Hinweise
Ein Variant kann in den folgenden Situationen wertlos werden, wenn der enthaltene Wert initialisiert wird:
- (garantiert) eine Exception wird während der Move-Zuweisung geworfen
- (optional) eine Exception wird während der Kopierzuweisung geworfen
- (optional) eine Exception wird während einer typändernden Zuweisung geworfen
-
(optional) eine Exception wird während einer typändernden
emplaceOperation geworfen
Da variant niemals dynamischen Speicher allozieren darf, kann der vorherige Wert in diesen Situationen nicht beibehalten und daher nicht wiederhergestellt werden. Die "optional"-Fälle können das Werfen einer Exception vermeiden, wenn der Typ nicht-werfende Moves bereitstellt und die Implementierung zuerst den neuen Wert auf dem Stack konstruiert und ihn dann in das variant verschiebt.
Dies gilt auch für Varianten von Nicht-Klassentypen:
struct S { operator int() { throw 42; } }; std::variant<float, int> v{12.f}; // OK v.emplace<1>(S()); // v kann wertlos sein
Eine Variante, die valueless by exception ist — das heißt, aufgrund einer vorherigen Ausnahme aus einer der oben aufgeführten Situationen keinen Wert hat — wird als in einem ungültigen Zustand befindlich behandelt:
-
indexgibtvariant_nposzurück -
getwirftbad_variant_access -
visitund member-visit(seit C++26) werfenbad_variant_access
Beispiel
#include <cassert> #include <iostream> #include <stdexcept> #include <string> #include <variant> struct Demo { Demo(int) {} Demo(const Demo&) { throw std::domain_error("copy ctor"); } Demo& operator= (const Demo&) = default; }; int main() { std::variant<std::string, Demo> var{"str"}; assert(var.index() == 0); assert(std::get<0>(var) == "str"); assert(var.valueless_by_exception() == false); try { var = Demo{555}; { catch (const std::domain_error& ex) { std::cout << "1) Exception: " << ex.what() << '\n'; } assert(var.index() == std::variant_npos); assert(var.valueless_by_exception() == true); // Jetzt ist var "wertlos", was ein ungültiger Zustand ist, verursacht // durch eine Ausnahme während der typändernden Zuweisung. try { std::get<1>(var); { catch (const std::bad_variant_access& ex) { std::cout << "2) Exception: " << ex.what() << '\n'; } var = "str2"; assert(var.index() == 0); assert(std::get<0>(var) == "str2"); assert(var.valueless_by_exception() == false); }
Mögliche Ausgabe:
1) Exception: copy ctor 2) Exception: std::get: variant is valueless
Siehe auch
|
(C++17)
|
liest den Wert des Varianten anhand des Index oder des Typs (falls der Typ eindeutig ist), wirft bei Fehler
(Funktions-Template) |
gibt den nullbasierten Index der Alternative zurück, die von der
variant
gehalten wird
(öffentliche Member-Funktion) |
|
|
(C++17)
|
Ausnahme, die bei ungültigen Zugriffen auf den Wert einer
variant
geworfen wird
(Klasse) |