It's fine according to the lookup rules. You see, when you write member access (obj.display();
), the member display
is looked up not just in the scope of the class and its base classes. Base class sub-objects are taken into consideration as well.
If the member being looked up is not static, since base class sub-objects are part of the consideration, and you have two sub-objects of the same type, there's an ambiguity in the lookup.
But when they are static, there is no ambiguity. And to make it perfectly clear, the C++ standard even has a (non-normative) example when it describes class member lookup (in the section [class.member.lookup]):
[ Note: A static member, a nested type or an enumerator defined in a
base class T can unambiguously be found even if an object has more
than one base class subobject of type T. Two base class subobjects
share the non-static member subobjects of their common virtual base
classes. — end note ] [ Example:
struct V {
int v;
};
struct A {
int a;
static int s;
enum { e };
};
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };
void f(D* pd) {
pd->v++; // OK: only one v (virtual)
pd->s++; // OK: only one s (static)
int i = pd->e; // OK: only one e (enumerator)
pd->a++; // error, ambiguous: two as in D
}
— end example ]