c++inheritancemember-functionsname-lookupname-hiding

Question about C++ call virtual function implemented in base from derived class


What is wrong with the following code?

struct A {
  virtual int hash() const = 0;
  virtual int hash(int x) const = 0;
};

struct B : public A {
  int hash() const final {
    return 10;
  };

  int hash(int x) const override {
    return 10;
  };
};

struct C : public B {
  int hash(int x) const override {
    return x;
  }
};

#include <iostream>

int main() {
  C a;
  std::cout << a.hash() << std::endl;
  std::cout << a.hash(20) << std::endl;
  return 0;
}

I got compile error with the following error message

xx.cc:26:23: error: too few arguments to function call, single argument 'x' was
      not specified
  std::cout << a.hash() << std::endl;
               ~~~~~~ ^
xx.cc:17:3: note: 'hash' declared here
  int hash(int x) const override {
  ^
1 error generated.

Solution

  • This is name hiding issue. According to the rule of name lookup,

    (emphasis mine)

    name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

    So C::hash hides the name from the base class.

    You can apply using to introduce the name into the class C scope.

    struct C : public B {
      using B::hash;
      int hash(int x) const override {
        return x;
      }
    };