Namespaces
Variants

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

From cppreference.net
Utilities library
constexpr bool valueless_by_exception ( ) const noexcept ;
(depuis C++17)

Retourne false si et seulement si la variante contient une valeur.

Notes

Une variante peut devenir sans valeur lors de l'initialisation de la valeur contenue dans les situations suivantes :

Puisque le variant n'est jamais autorisé à allouer de la mémoire dynamique, la valeur précédente ne peut être conservée et, par conséquent, restaurée dans ces situations. Les cas "optionnels" peuvent éviter de lever une exception si le type fournit des déplacements non-lancants et que l'implémentation construit d'abord la nouvelle valeur sur la pile puis la déplace dans le variant.

Cela s'applique même aux variantes de types non-classes :

struct S
{
    operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // OK
v.emplace<1>(S()); // v peut être sans valeur

Un variant qui est valueless by exception — c'est-à-dire qui n'a aucune valeur en raison d'une exception antérieure provenant de l'une des situations mentionnées ci-dessus — est considéré comme étant dans un état invalide :

Exemple

#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);
    // Maintenant le variant est "sans valeur", un état invalide causé
    // par une exception levée lors de l'assignation changeant de type.
    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);
}

Sortie possible :

1) Exception: copy ctor
2) Exception: std::get: variant is valueless

Voir aussi

lit la valeur du variant donné l'index ou le type (si le type est unique), lance une exception en cas d'erreur
(modèle de fonction)
retourne l'index de base zéro de l'alternative contenue par le variant
(fonction membre publique)
exception lancée lors d'accès invalides à la valeur d'un variant
(classe)