Class member access using qualified-id in case of ambiguity

Viewed 94

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?

1 Answers

Clang is correct according to the recent clarification of that wording, which now says

If nothing is found by qualified lookup for a member-qualified name that is the terminal name ([expr.prim.id.qual]) of a nested-name-specifier and is not dependent, it undergoes unqualified lookup.

Now there is no problematic “the name, if found” which could imply uniqueness.

Related