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?
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::
orB::
qualifiers, the definition ofC::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.