2

Consider the following example:

struct Base
{
    virtual void fun() = 0;
    void fun(float) { fun(); }
};

struct Derived : Base
{
    void fun() override {}
    void bar()
    {
        // calling Base1::fun from, which in turn should call Derived::fun
        fun(42.42f); // error "Function does not take 1 argument"
        Base::fun(42.42f); // ok
    }
};

Why is it necessary to specify the scope of fun in such a case? Shouldn't the base class's fun be taken into account implicitly?

Why does removing the definition of Derived::fun cause a successful compilation?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
DeiDei
  • 10,205
  • 6
  • 55
  • 80
  • 1
    Another way to solve your problem is to have `using Base::fun;` in the `Derived` class. That pulls in all variants of `Base::fun` into the scope of the `Derived` class. – Some programmer dude Jun 18 '17 at 13:53

2 Answers2

3

Overloading won't take place through different scopes.

For fun(42.42f);, the name fun has to be found. According to the rule of unqualified name lookup:

For an unqualified name, that is a name that does not appear to the right of a scope resolution operator ::, 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.

That means the name will be found at the scope of class Derived, i.e. Derived::fun(). Then the name lookup stops, the names in the scope of Base won't be considered at all.

If you remove the definition of Derived::fun, there would be no names found at the scope of Derived, then the scope of the base class (i.e. Base) will be examined further and Base::foo will be found. Then everything works fine.

It's also worth noting that overload resolution happens after name lookup.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

This is caused because of Method Hiding, even tough the signatures differ. As Some programmer dude mentioned "If you use a symbol for a member in a child class that already exists in a base class, the symbols from the base class are hidden".

Please read more in Why does an overridden function in the derived class hide other overloads of the base class?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • That seems illogical to me since the *hidden method* is of a different signature. – DeiDei Jun 18 '17 at 13:52
  • @DeiDei No matter how "illogical" you might think it is, that's how C++ works and is designed. If you use a symbol for a member in a child class that already exists in a base class, the symbols from the base class are hidden. – Some programmer dude Jun 18 '17 at 13:54
  • @DeiDei answer updated, hope it helps now! Some programmer dude is right, injected that into my answer! =) – gsamaras Jun 18 '17 at 13:57
  • 1
    @DeiDei It avoids the [brittle base class](https://stackoverflow.com/a/2933724/902497) problem. – Raymond Chen Jun 18 '17 at 14:06