考虑:
#include <variant>
#include <iostream>
int main()
{
double foo = 666.666;
std::variant<double, uint64_t> v = foo;
std::cout << std::get<uint64_t>(v) << std::endl;
return 0;
}
这导致:
terminate called after throwing an instance of 'std::bad_variant_access'
what(): Unexpected index
Aborted (core dumped)
为什么?
我已经了解到std::variant
将替代union
。但是,如果这种基本的东西失败了,那有什么用呢?
我知道std :: variant将替代union。
是。有点儿。但是您的误解似乎与C ++中的联合有关。从cppreference:
从最近未写的工会成员那里读来的行为是不确定的。作为非标准语言扩展,许多编译器都实现了读取联合中不活动成员的功能。
请注意,这与C不同,这是常见的误解的根本原因,该误解是在C ++中也允许访问非活动成员。
为什么?
因为std::variant
模仿联合但增加了一些安全性,并且std::get
是...
基于索引的值访问器:如果v.index()== I,则返回对v中存储的值的引用。否则,抛出std :: bad_variant_access。如果我不是,则调用格式错误变体中的有效索引。
。
但是,如果这种基本的东西失败了,那有什么用呢?
C ++中的联盟绝不会那样使用。如果要将两个或多个值压缩到同一内存中,则并集可以节省内存(但在任何时候都只能使用其中一个)。我从来没有遇到过真正的用例。但是std::get
是C ++类型的不错补充。更大的图景是很长一段时间以来已经存在所谓的产品类型,例如std::variant
,从某种意义上来说,它们可以表示的值集为std::pair<T1,T2>
。现在有了T1 x T2
(和std::variant
),C ++也具有适当的(=从某种程度上从未从并集获得类型安全性)和类型,即std::any
可以表示的一组值是std::variant<T1,T2>
(对不起使用草率的表示法,希望很清楚)。
T1 + T2
是一个“类型安全的联合”,这意味着它将检查您从中得到的是最后存储在其中的类型。在此示例中,您存储的是std::variant
,但尝试获取double
。
请在此处查看文档:uint64_t
基于类型的值访问器:如果v持有替代T,则返回对v中存储的值的引用。否则,抛出std :: bad_variant_access。如果T不是Types的唯一元素,则呼叫格式不正确。