Namespaces
Variants

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

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

Devuelve false si y solo si la variante contiene un valor.

Notas

Una variante puede quedar sin valor al inicializar el valor contenido en las siguientes situaciones:

Dado que a variant nunca se le permite asignar memoria dinámica, el valor anterior no puede ser retenido y, por lo tanto, restaurado en estas situaciones. Los casos "optional" pueden evitar lanzar una excepción si el tipo proporciona movimientos no lanzadores y la implementación primero construye el nuevo valor en el stack y luego lo mueve al variant.

Esto se aplica incluso a variantes de tipos no clase:

struct S
{
    operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // CORRECTO
v.emplace<1>(S()); // v puede quedar sin valor

Una variante que está sin valor por excepción — es decir, no tiene valor debido a una excepción previa de una de las situaciones enumeradas anteriormente — se trata como si estuviera en un estado inválido:

Ejemplo

#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);
    // Ahora el var está "sin valor" (valueless), que es un estado inválido causado
    // por una excepción generada durante el proceso de asignación con cambio de tipo.
    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);
}

Salida posible:

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

Véase también

lee el valor del variant dado el índice o el tipo (si el tipo es único), lanza una excepción en caso de error
(plantilla de función)
devuelve el índice basado en cero de la alternativa contenida por el variant
(función miembro pública)
excepción lanzada en accesos inválidos al valor de un variant
(clase)