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