为什么我得到 std::bad_variant_access 和 std::variant?
Why I'm getting std::bad_variant_access with std::variant?
考虑:
#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
。但是,如果这种基本的东西失败了,它有什么好处?
I have understood that std::variant would be a replacement for union.
是的。有点儿。但是您的误解似乎与 C++ 中的联合有关。来自 cppreference:
It's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.
请注意,这与 C 不同,这是导致 C++ 也允许访问非活动成员的常见误解的根本原因之一。
Why?
因为 std::variant
模仿联合但增加了一些安全性 std::get
是...
Index-based value accessor: If v.index() == I, returns a reference to the value stored in v. Otherwise, throws std::bad_variant_access. The call is ill-formed if I is not a valid index in the variant.
.
But if this kind of basic stuff fails what is it good for?
C++ 中的联合从来就不是这样使用的。当您想将两个或多个值压缩到同一内存中(但任何时候只使用其中一个)时,联合更节省内存。我从来没有遇到过他们的真实用例。然而,std::variant
是对 C++ 类型的一个很好的补充。更大的图景是,很久以来就存在所谓的产品类型,例如 std::pair<T1,T2>
,从某种意义上说,它们可以表示的值集是 T1 x T2
。使用 std::variant
(和 std::any
),现在 C++ 也有适当的(= 具有一定程度的类型安全性,你从未从联合中获得)总和类型,即 std::variant<T1,T2>
可以表示的值集是T1 + T2
(抱歉使用草率的符号,希望它清楚)。
std::variant
是一个“类型安全的联合”,这意味着它会检查你从中得到的是最后存储在其中的类型。在此示例中,您正在存储 double
但试图获取 uint64_t
.
在此处查看文档:
https://en.cppreference.com/w/cpp/utility/variant/get
Type-based value accessor: If v holds the alternative T, returns a reference to the value stored in v. Otherwise, throws std::bad_variant_access. The call is ill-formed if T is not a unique element of Types....
考虑:
#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
。但是,如果这种基本的东西失败了,它有什么好处?
I have understood that std::variant would be a replacement for union.
是的。有点儿。但是您的误解似乎与 C++ 中的联合有关。来自 cppreference:
It's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.
请注意,这与 C 不同,这是导致 C++ 也允许访问非活动成员的常见误解的根本原因之一。
Why?
因为 std::variant
模仿联合但增加了一些安全性 std::get
是...
Index-based value accessor: If v.index() == I, returns a reference to the value stored in v. Otherwise, throws std::bad_variant_access. The call is ill-formed if I is not a valid index in the variant.
.
But if this kind of basic stuff fails what is it good for?
C++ 中的联合从来就不是这样使用的。当您想将两个或多个值压缩到同一内存中(但任何时候只使用其中一个)时,联合更节省内存。我从来没有遇到过他们的真实用例。然而,std::variant
是对 C++ 类型的一个很好的补充。更大的图景是,很久以来就存在所谓的产品类型,例如 std::pair<T1,T2>
,从某种意义上说,它们可以表示的值集是 T1 x T2
。使用 std::variant
(和 std::any
),现在 C++ 也有适当的(= 具有一定程度的类型安全性,你从未从联合中获得)总和类型,即 std::variant<T1,T2>
可以表示的值集是T1 + T2
(抱歉使用草率的符号,希望它清楚)。
std::variant
是一个“类型安全的联合”,这意味着它会检查你从中得到的是最后存储在其中的类型。在此示例中,您正在存储 double
但试图获取 uint64_t
.
在此处查看文档: https://en.cppreference.com/w/cpp/utility/variant/get
Type-based value accessor: If v holds the alternative T, returns a reference to the value stored in v. Otherwise, throws std::bad_variant_access. The call is ill-formed if T is not a unique element of Types....