Closed Quuxplusone closed 6 years ago
Slightly simpler:
template<typename V> auto get(V&) { }
template<typename>
class variant
{
template<typename V> friend auto get(V&);
};
int main()
{
variant<int> v{};
get(v);
}
var.cc:12:3: error: call to 'get' is ambiguous
get(v);
^~~
var.cc:1:27: note: candidate function [with V = variant<int>]
template<typename V> auto get(V&) { }
^
var.cc:6:38: note: candidate function [with V = variant<int>]
template<typename V> friend auto get(V&);
^
1 error generated.
This is affecting libstdc++ trunk
Got bit by this again. This is probably a duplicate of: https://bugs.llvm.org/show_bug.cgi?id=33222
Minimal example to reproduce the "is a private member" error:
template <typename U>
auto foo(U u)
{
u.v;
}
template <typename T>
class X
{
T v;
public:
template <typename U>
friend auto foo(U);
};
int main()
{
::foo(X<int>{});
}
(In reply to Tim Shen from comment #2)
> This is affecting libstdc++ trunk <variant> as well.
I've added a workaround in https://gcc.gnu.org/r258854
(In reply to Jonathan Wakely from comment #4)
> (In reply to Tim Shen from comment #2)
> > This is affecting libstdc++ trunk <variant> as well.
>
> I've added a workaround in https://gcc.gnu.org/r258854
The calls to __get() in variant's operators are also causing ambiguity errors:
include/c++/7.3.0/variant:287:3: error: call to '__get' is ambiguous
_VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Patch against trunk:
@@ -272,8 +272,8 @@
constexpr bool \
__erased_##__NAME(const _Variant& __lhs, const _Variant& __rhs) \
{ \
- return __get<_Np>(std::forward<_Variant>(__lhs)) \
- __OP __get<_Np>(std::forward<_Variant>(__rhs)); \
+ return __variant::__get<_Np>(std::forward<_Variant>(__lhs)) \
+ __OP __variant::__get<_Np>(std::forward<_Variant>(__rhs)); \
}
_VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
Thanks, fixed on trunk by r259135
Thanks, this has been fixed in r341775.
Hi,
The following code does not compile under Clang trunk
template class Template;
template <typename T, typename ...X> class Specialized;
template <typename T, typename ...X> class Specialized<T, Template...> {
template friend auto f();
static constexpr int member = 0;
};
template
auto f() { (void)Specialized::member; }
template auto f();
The error is
test.cpp:11:34: error: 'member' is a private member of 'Specialized'
auto f() { (void)Specialized::member; }
^
test.cpp:13:15: note: in instantiation of function template specialization 'f' requested here
template auto f();
^
test.cpp:7:14: note: implicitly declared private here
static int member;
^
1 error generated.
Live example on Wandbox: http://melpon.org/wandbox/permlink/aEH7GireSTaP0n3x Note that GCC compiles this fine: http://melpon.org/wandbox/permlink/Zdckf85spwKr7yqa
Also note that using
void
instead ofauto
as the return type off()
fixes the problem: http://melpon.org/wandbox/permlink/TOH067rDrJIcweiC