请考虑以下代码段:
struct v : std::variant<int, std::vector<v>> { };
int main()
{
std::visit([](auto){ }, v{0});
}
- clang 7用
-stdlib=libc++ -std=c++2a
编译代码;
带有 -std=c++2a
的
- g 9无法编译代码,并出现以下错误:
/ opt / compiler-explorer / gcc-trunk-20180711 / include / c /9.0.0/variant:94:29:错误:不完整类型'std :: variant_size'用于嵌套名称说明符inline constexpr size_t variant_size_v = variant_size < _Variant> ::值;
^ ~~~~~~~~~~~~~
-
Are both implementations conforming to the Standard?
-
如果没有,这里的实施是正确的,为什么?
2 回答
[variant.visit] in C++17不使用
variant_size_v
,但它在current working draft中作为editorial change的结果 . 我不会假定它实际上是必需的 .与此同时,已被提交给LEWG的LWG issue 3052明确要求
std::variant
. 当问题得到解决时 - 无论如何 - 它也应该解决这个问题 .看起来它是gcc实现中的一个错误 . 根据cppreference,它被调用,好像在
std::get
上调用invoke
.std::get<>
是为可转换为std::variant
的任何内容定义的(因为它通过转发引用接受std::variant
参数) . 您的结构可以转换为std::variant
,因此std::get
本身适用于您在gcc中的结构 .gcc实现选择使用
std::variant_size
作为其visit
实现的一部分这一事实是它们的实现细节,而且它对于你的结构没有用的事实是无关紧要的 .结论:由于实施中的疏忽,这是gcc中的一个错误 .