c++inheritancevirtual-inheritancediamond-problem

C++ Multipath Inheritance : Why the access using Base class scope is non-ambiguous?


I am studying C++ and while studying virtual inheritance, I came across following doubt:

class A {
public:
    int x;
    A() { x = 677; }
    A(int a) { 
        cout << "A con , x= " << a << endl;
        x = a;
    }
};
class B : public A {
public:
    B(int a) : A(a) { }
};
class C :public A {
public:
    C(int a) : A(a) { }
};
class D : public B, public C {
public:
    D(int a,int b) : B(a),C(b) { }
};
int main()
{
    D d(5,6);
    cout << d.A::x;  //prints 5 
 }

In line cout << d.A::x; It prints 5. Shouldn't this call be ambiguous and if not why it prints 5?


Solution

  • d.A::x; is indeed ambiguous. GCC and Clang report it as error, only MSCV fails to do so: https://godbolt.org/z/1zhjdE6a8.

    There is a note in [class.mi] with an example of multiple inheritance stating that:

    In such lattices, explicit qualification can be used to specify which subobject is meant. The body of function C​::​f can refer to the member next of each L subobject:

    void C::f() { A::next = B::next; }      // well-formed
    

    Without the A​::​ or B​::​ qualifiers, the definition of C​::​f above would be ill-formed because of ambiguity ([class.member.lookup]). — end note]

    It is just a note, because it follows from [class.member.lookup] (which is a little more contrived to read and understand) that without the qualifier the member access is ambiguous. "ill-formed" implies that a conforming compiler must issue either an error or warning.