The following code:
variant x = \"abc\";
cout << get(x) << \"\\n\";
works fine under g++ (version 7
This is caused by clang bug 31852 (and also 33222), whose reproduction courtesy of Jonathan Wakely should look very relevant:
template auto get(V&) { }
template
class variant
{
template friend auto get(V&);
};
int main()
{
variant v{};
get(v); // error: ambiguous
}
clang doesn't properly recognize friend declarations that have placeholder types. Which is exactly how libstdc++ implements std::get:
// Returns the typed storage for __v.
template
constexpr decltype(auto) __get(_Variant&& __v)
{
return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);
}
this accesses a private member of variant, but this function is properly declared a friend:
template
friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v);
libstdc++'s implementation is valid, clang just doesn't think __get is a friend.