首页 文章

在继承自std :: variant的类上使用std :: visit - libstdc vs libc

提问于
浏览
15

请考虑以下代码段:

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> ::值;

^ ~~~~~~~~~~~~~

live example on godbolt.org


  • Are both implementations conforming to the Standard?

  • 如果没有,这里的实施是正确的,为什么?

2 回答

  • 12

    [variant.visit] in C++17不使用 variant_size_v ,但它在current working draft中作为editorial change的结果 . 我不会假定它实际上是必需的 .

    与此同时,已被提交给LEWG的LWG issue 3052明确要求 std::variant . 当问题得到解决时 - 无论如何 - 它也应该解决这个问题 .

  • 8

    看起来它是gcc实现中的一个错误 . 根据cppreference,它被调用,好像在 std::get 上调用 invoke . std::get<> 是为可转换为 std::variant 的任何内容定义的(因为它通过转发引用接受 std::variant 参数) . 您的结构可以转换为 std::variant ,因此 std::get 本身适用于您在gcc中的结构 .

    gcc实现选择使用 std::variant_size 作为其 visit 实现的一部分这一事实是它们的实现细节,而且它对于你的结构没有用的事实是无关紧要的 .

    结论:由于实施中的疏忽,这是gcc中的一个错误 .

相关问题