Namensräume
Varianten
Aktionen

std::variant<Types...>::valueless_by_exception

Von cppreference.com
< cpp‎ | utility‎ | variant
 
 
Dienstprogramm-Bibliotheken
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Coroutine-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationale Operatoren (in C++20 veraltet)
 
 
constexpr bool valueless_by_exception() const noexcept;
(seit C++17)

Gibt false genau dann zurück, wenn das variant einen Wert enthält.

[bearbeiten] Anmerkungen

Ein variant kann beim Initialisieren des enthaltenen Wertes in folgenden Situationen wertlos werden:

  • (garantiert) eine Ausnahme wird während der Verschiebezuweisung ausgelöst
  • (optional) eine Ausnahme wird während der Kopierzuweisung ausgelöst
  • (optional) eine Ausnahme wird während einer typverändernden Zuweisung ausgelöst
  • (optional) eine Ausnahme wird während eines typverändernden emplace ausgelöst

Da variant niemals dynamischen Speicher zuweisen darf, kann der vorherige Wert in diesen Situationen nicht beibehalten und somit nicht wiederhergestellt werden. Die "optionalen" Fälle können das Auslösen einer Ausnahme vermeiden, wenn der Typ nicht-ausnahmeauslösende Verschiebungen bereitstellt und die Implementierung zuerst den neuen Wert auf dem Stack konstruiert und ihn dann in das variant verschiebt.

Dies gilt auch für variants von Nicht-Klassen-Typen.

struct S
{
    operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // OK
v.emplace<1>(S()); // v may be valueless

Ein variant, das wertlos durch Ausnahme ist — d. h. keinen Wert aufgrund einer früheren Ausnahme aus einer der oben genannten Situationen hat — wird als in einem ungültigen Zustand behandelt.

[bearbeiten] 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);
 
    // Now the var is "valueless" which is an invalid state caused
    // by an exception raised in the process of type-changing assignment.
 
    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

[bearbeiten] Siehe auch

liest den Wert des variants anhand des Index oder des Typs (wenn der Typ eindeutig ist), wirft bei Fehler
(function template) [bearbeiten]
gibt den nullbasierten Index der vom variant gehaltenen Alternative zurück
(public member function) [bearbeiten]
Ausnahme, die bei ungültigen Zugriffen auf den Wert eines variant geworfen wird
(class) [bearbeiten]