Consider a struct B
derived from two structs A<1>
and A<2>
, each defining a typename D
to itself, and there is also a global typename D
. Then one writes .D::
after a B
object , which D
must be taken?
template<int N> struct A{ int v = N; using D = A; };
struct B : A<1>, A<2> {};
using D = A<1>;
int main() { return B{}.D::v; }
According to the standard: [basic.lookup.classref]
4 If the id-expression in a class member access is a qualified-id of the form
class-name-or-namespace-name::...
the
class-name-or-namespace-name
following the.
or->
operator is first looked up in the class of the object expression ([class.member.lookup]) and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression.
So, first D
must be looked inside struct B
, but it is ambiguous there. And indeed, Clang reports an error about it:
error: member 'D' found in multiple base classes of different types
But GCC accepts the code, demo: https://gcc.godbolt.org/z/74qraoeac
It seems that GCC interprets the standard as if D
is ambiguous in B
, let us look outside of B
. Which compiler is correct here?