A derived class’s member-initialization list can initialize any non-ambiguous member of its class, including base subobjects. Suppose you have a class C that is derived from B, which is in turn derived from A:
struct A { A(int a); }; struct B : public A { B(int b); }; struct C: public B { C(): B(5), A(5) {} // error: 'A' is ambiguous };
You want to initialize A from C’s constructor. Your compiler complains that: “‘A’ is not an unambiguous base class of ‘C’.” The problem is that A’s immediate descendant, namely B, is supposed to initialize A but you try to initialize it in C, too. To enable this initialization, make the A subobject a non-ambiguous base using virtual inheritance:
struct B : virtual public A { B(int b); };
Now you can initialize A from any other derived class, not just from B:
struct C: public B { C(): B(5), A(5) {} // OK, A is a virtual base class };