Search code examples
c++language-lawyermultiple-inheritance

How to call a hidden method from two times inherited base class in C++?


Consider a class D inherited from two classes B and C, each of which inherits not-virtually class A. There is a method f in A, and the same named method in B hiding the method from A. I would like to call A::f() from B-base class of D object as follows:

struct A { void f() {} };
struct B : A { void f() {} };
struct C : A {};
struct D : B, C {};
int main() { D{}.B::A::f(); }

Unfortunately, it works only in MSVC, while both GCC and Clang produce the error:

error: 'A' is an ambiguous base of 'D'

demo: https://gcc.godbolt.org/z/jY3v876hK

It looks like GCC/Clang accept but completely ignore B:: prefix in B::A::f(). Are they right in doing so according to the standard?


Solution

  • Are they right in doing so according to the standard?

    Yes. The nested name specifier in A::, B::A, or D::B::A all serve the same purpose, to name the class A.

    [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.

    The nested name specifier does not name "a path" to the member, it names a base of D. And to name A results in ambiguity.