Consider the code
struct Base{};
struct Derived: public Base{};
struct A: public Base{};
struct B: public A, public Base{};
struct C: public A, public Derived{}; // why no ambiguity here?
int main() {}
The compiler (g++5.1) warns that
warning: direct base
'Base'inaccessible in'B'due to ambiguitystruct B: public A, public Base{};
I understand this, Base is duplicated in B.
Why is there no warning for
C? Doesn'tCinherit from bothAandDerived, which both inherit fromBase?Why adding
virtualstruct Derived: virtual Base{};
results now in both B and C emitting warnings, live on Wandbox
warning: direct base
'Base'inaccessible in'B'due to ambiguitystruct B: public A, public Base{};warning: direct base
'Base'inaccessible in'C'due to ambiguitystruct C: public A, public Derived{};
Bgives a warning. However what I don't understand is whyCis OK.CbecauseBaseis ambiguous in that case too. When you virtually derive fromBasethe most derived class (C) is responsible for calling theBaseconstructor, and so gcc starts detecting the ambiguity again.struct Derived: public virtual BaseCI can addressBase's members by explicitly qualifying them. SayBasehad a member functionvoid foo(){}. Then I can sayC{}.A::foo(); C{}.Derived::foo();, but as far as I can tell, there's no way to do that withB.