If we are talking about Visual Studio, then this is apparently a compiler bug.
For some reason, the Visual Studio d.print() decides in such a situation to implement the d.print() call as a full-fledged virtual call through the class D virtual functions table. (In this, incidentally, there is still no error.) But to resolve this virtual call, he certainly takes the first table in an object of type D (from the first base in the list of databases), for which reason such virtual calls always fall into B::print . If you swap the bases in the class D declaration, then C::print will be called all the time.
If you make the print function non-virtual, then the problem disappears. If you explicitly make the call non-virtual, i.e. instead of d.print() calling dD::print() , then the problem disappears.
This is actually an interesting topic. The d.print() call is a virtual call from the point of view of the language and should be resolved based on the dynamic type of the object d . Those. The final overrider must be taken from class D And who is the final overrider in D ? (More precisely, from which chain of bases should it be selected: A->B->D or A->С->D ?). Using-declaration cannot be used to resolve this issue. The standard has a good example on this topic.
struct A { virtual void f(); }; struct B : virtual A { virtual void f(); }; struct C : B , virtual A { using A::f; }; void foo() { C c; cf(); // calls B::f, the final overrider cC::f(); // calls A::f because of the using-declaration }
Note that cf() should call B::f() despite the presence of using A::f in C
Apparently, in our example, everything starts with the name lookup, which should use the using-declaration using C::print and localize the review in the A->C inheritance branch, where the final overrider is unambiguous.
Dwill have to implement theprintfunction itself, since it will directly inherit and initialize an instance of classATheusingdirective only affects the detection of names; it does not allow the implementation of methods to be added to a class. - VTTAinherited virtually, then there would be an error in the code about the absence of a final overrider inD, which is not related tousingat all. - AnT