代码之家  ›  专栏  ›  技术社区  ›  Vittorio Romeo

使用STD:访问继承STD::变体-LBSTDC++VB+LBC++

  •  15
  • Vittorio Romeo  · 技术社区  · 7 年前

    请考虑以下代码段:

    struct v : std::variant<int, std::vector<v>> { };
    
    int main()
    {
        std::visit([](auto){ }, v{0});
    }
    
    • clang++7与 -stdlib=libc++ -std=c++2a 编译代码;

    • G++9与 -std=c++2a 未能编译代码,出现以下错误:

      /opt/编译器资源管理器/GCC-Tunun-20180711/Eng/C++/0.0.0/变体:94:29: 错误:嵌套名称中使用的不完整类型“STD::变量大小” 说明符

       inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
      
                               ^~~~~~~~~~~~~~
      

    live example on godbolt.org


    • 两种实现都符合标准吗?

    • 如果不是,那么这里什么实现是正确的,为什么呢?

    2 回复  |  直到 7 年前
        1
  •  12
  •   T.C. Yksisarvinen    7 年前

    [variant.visit] in C++17 不使用 variant_size_v 但是它在 current working draft 由于 editorial change . 我看不到任何迹象表明LWG在进入之前审查了这一变化,但从那时起它已经多次审查了标准的这一部分,并且还没有反对它,所以我假设它实际上是必需的。

    同时, LWG issue 3052 被称为LEWG,将明确要求 std::variant . 当这个问题得到解决——不管是一种还是另一种——它也应该解决这个问题。

        2
  •  8
  •   callyalater ingleback    7 年前

    看起来这是gcc实现中的一个bug。根据 cppreference ,就像在呼叫 invoke 在一 std::get . std::get<> 是为任何可转换为 std::variant (因为它接受 STD::变异型 通过转发引用的参数)。您的结构可转换为 STD::变异型 等等。 STD::得到 它在GCC中的结构上工作。

    GCC实现选择使用 std::variant_size 作为其实施的一部分 visit 是它们的实现细节,而它不(也不应该)适用于您的结构这一事实是不相关的。

    结论:由于实施过程中的监督,这是GCC中的一个缺陷。