Search code examples
c++diamond-problem

In C++ are static member functions inherited? If yes why ambiguity error does not arise?


I am just starting out with gnu-cpp and would like some help. I have come across the ambigutity error while reading and while self-study I came across this idea that static methods of a class should also be affected by the ambiguous diamond problem, but while running the following code ther is no error. Can anyone please explain why?

#include<iostream>
using namespace std;
class Base
{
  public:
  static void display(){cout<<"Static";}
};
class Derived1 : public Base {};
class Derived2 : public Base {};
class Child : public Derived1, Derived2 {};
int main(void)
{
  Child obj;
  obj.display();
}

Thank You for the help and time.


Solution

  • 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 ]