std::variant<Types...>::valueless_by_exception
来自 cppreference.com
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 may be valueless
通过异常变为无值的变体被视为处于无效状态:index
返回 variant_npos
,get
和 visit
抛出 bad_variant_access
。
[编辑] 示例
运行此代码
#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); // Now the var is "valueless" which is an invalid state caused // by an exception raised in the process of type-changing assignment. 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
[编辑] 另请参阅
(C++17) |
读取变体的值,给出索引或类型(如果类型是唯一的),在错误时抛出异常 (函数模板) |
返回 variant 持有的备选方案的基于零的索引(公共成员函数) | |
(C++17) |
在对 variant 的值进行无效访问时抛出的异常(类) |