In the code below, I get the following warning and error:
test.cpp:15: warning: direct base 'B' inaccessible in 'D' due to ambiguity
test.cpp:15: error: no unique final overrider for 'virtual void A::f()' in 'D'
But if I remove the virtual inheritance of B from A (i.e. struct B : public A
), I only get the warning, no error.
struct A
{
virtual void f() = 0;
};
struct B : public virtual A
{
void f() {}
};
class C : public B
{};
struct D : public C, virtual B
{};
int main()
{
return 0;
}
Why? Is this the dreaded diamond?
It's because C
inherits in a non-virtual way from B
while D
inherits in a virtual way from B
. This gives you B
two times including two f()
.
Try virtual inheritance of B
in C
.
Update: So why does it work when you remove the virtual inheritance in B
from A
? Because it changes the "final overrider". Without virtual in B
from A
and in C
from B
you have A
two times: once in C
(with the final override of f()
in B
) and once in the virtual B
in D
(with the final override of f()
in B
). If you add back the virtual inheritance in B
to A
, A
will be present only once and there will be two final overrides competing to implement the pure f()
from A
, both in B
, once from C
and once from the virtual B
.
As a workaround you could add a using
to D, that is using C::f;
or using B::f
.
See C++ 10.3/2