在clang 5下,使用std::visit访问variant时编译失败

11

以下代码在gcc 7.2下可以正常编译,但在clang 5.0下无法编译。请问有人知道问题出在哪里吗?


Translated text: "The following code compiles properly under gcc 7.2 but fails to compile under clang 5.0. Does anyone know what the problem is?"
#include <variant>

struct S1 {int foo() { return 0; }};
struct S2 {int foo() { return 1; }};

using V = std::variant<S1, S2>;

int  bar() {
  V v;
  return std::visit([](auto& s) { return s.foo(); }, v);
}

第一个错误是:

include/c++/7.2.0/variant:238:46: error: cannot cast 'std::variant<S1, S2>' to its private base class
  'std::__detail::__variant::_Variant_storage<true, S1, S2>'
  return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);

这里有一个链接到godbolt,显示了这个错误:https://godbolt.org/g/5iaKUm


可能 libstdc++ 的变体使用了 Clang 不支持的非标准特性。它可以通过 -stdlib=libc++ 编译。 - chris
注意 std::get<0>(v), std::get<S1>(v) 等都会失败并抛出基本相同的错误(且中间实例化步骤更少)。 - aschepler
确实,错误的原因似乎是相同的,所以我们可以将其视为重复。 - user2736667
1个回答

11

这是已知的33222号错误,似乎只影响libstdc++的std::variant(以及使用相同组合的其他结构)。该问题与友元函数模板有关 - 有关详细信息请参见线程。

来自libc++的变体似乎不使用libstdc++所用的友元技术,因此您可能希望暂时改为使用libc++。

小更新:这已在最新的trunk中修复。


{btsdaf} - user2736667
2
{btsdaf} - Rakete1111
@user2736667 小更新:终于修复了这个漏洞! :) - Rakete1111

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接