Namespaces
Variants

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

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

当且仅当变体持有值时返回 false

注释

在以下情况中,当初始化所含值时,variant 可能变为无值:

由于 variant 绝不允许分配动态内存,因此在上述情况下无法保留并恢复先前的值。若类型提供不抛出异常的移动操作,且实现先在栈上构造新值再将其移入 variant,则"可选"情形可避免抛出异常。

这甚至适用于非类类型的变体:

struct S
{
    operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // 正常
v.emplace<1>(S()); // v 可能变为无值状态

一个处于 因异常而无值 状态的 variant —— 即由于先前在上述情形之一中发生异常而失去值的情况 —— 被视为处于无效状态:

示例

#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);
    // 现在 var 处于"无值"状态,这是在类型转换赋值过程中
    // 由异常引发的无效状态
    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);
}

可能的输出:

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

另请参阅

通过索引或类型(若类型唯一)读取 variant 的值,错误时抛出异常
(函数模板)
返回 variant 所持有可选项的从零开始的索引
(公开成员函数)
在无效访问 variant 值时抛出的异常
(类)