std::variant<Types...>::valueless_by_exception
来自cppreference.com
| |
(C++17 起) | |
当且仅当变体保有值时返回 false。
注解
变体可能在下列情形中初始化所含值而变得无值:
因为变体决不容许分配动态内存,故在这些情况下不可能保留并因此无法恢复先前的值。标为“可选”的情形,如果类型提供了不抛出移动,并且实现首先在栈上构造新值然后再把它移动到变体中,就可以避免抛出异常。
这也适用于非类类型的变体:
struct S
{
operator int() { throw 42; }
};
std::variant<float, int> v{12.f}; // OK
v.emplace<1>(S()); // v 可能为无值
因异常无值 的变体——即,由于之前有异常在以上列表中的情况之一中抛出而无值——被当做处于非法状态:
index返回variant_nposget抛出bad_variant_accessvisit与成员visit(C++26 起) 抛出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
参阅
(C++17) |
以给定索引或类型(如果类型唯一)读取 variant 的值,错误时抛出异常 (函数模板) |
返回 variant 所保有可选项的零基索引 (公开成员函数) | |
(C++17) |
非法地访问 variant 的值时抛出的异常 (类) |