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

来自cppreference.com
< cpp‎ | utility‎ | variant
 
 
工具库
语言支持
类型支持(基本类型、RTTI)
库功能特性测试宏 (C++20)
动态内存管理
程序工具
协程支持 (C++20)
变参数函数
调试支持
(C++26)
三路比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
初等字符串转换
(C++17)
(C++17)

 
 
constexpr bool valueless_by_exception() const noexcept;
(C++17 起)

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

注解

变体可能在下列情形中变得无值:

  • (保证)在移动赋值中,初始化所含值时抛出异常
  • (可选)在复制赋值中,初始化所含值时抛出异常
  • (可选)在类型更改赋值期间,初始化所含值时抛出异常
  • (可选)在类型更改 emplace 期间,初始化所含值时抛出异常

因为变体决不容许分配动态内存,故在这些情况下不可能保留先前的值。标为“可选”的情形可以被实现变通,它们首先在栈上构造新值然后再把它移动到变体中(只要移动不抛出)。

这也适用于非类类型的变体:

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

因异常无值的变体被当做处于非法状态:index 返回 variant_nposgetvisit 抛出 bad_variant_access

示例

#include <cassert>
#include <iostream>
#include <stdexcept>
#include <string>
#include <variant>
 
struct Demo
{
    Demo(int) {}
    Demo(const Demo&) { throw std::domain_error("复制构造函数"); }
    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{666};
    }
    catch (const std::domain_error& ex)
    {
        std::cout << "1) 异常: " << ex.what() << '\n';
    }
    assert(var.index() == std::variant_npos);
    assert(var.valueless_by_exception() == true);
 
    // 现在 var “无值”,此为 var 的初始化过程中引发的异常导致的非法状态。
 
    try
    {
        std::get<1>(var);
    }
    catch (const std::bad_variant_access& ex)
    {
        std::cout << "2) 异常: " << ex.what() << '\n';
    }
 
    var = "str2";
    assert(var.index() == 0);
    assert(std::get<0>(var) == "str2");
    assert(var.valueless_by_exception() == false);
}

可能的输出:

1) 异常: 复制构造函数
2) 异常: std::get: variant is valueless

参阅

以给定索引或类型(如果类型唯一)读取 variant 的值,错误时抛出异常
(函数模板)
返回 variant 所保有可选项的零基索引
(公开成员函数)
非法地访问 variant 的值时抛出的异常
(类)