2

I am having below code,

#include <iostream>
#include <string>
class Base {
public:
    void operator()(std::string str) {
        std::cout << "base str: " << str << std::endl;
    }

    virtual void operator()(double d) {
        std::cout << "base double: "<< d << std::endl;
    }

};

class Derived: public Base {
public:
    void operator()(double d) override {
        std::cout << "derived double: "<< d << std::endl;
    }
};

int main() {
    Derived derived;
    derived(8.0);
    derived(std::string("hi"));
}

The above code wont compile as it will complain that no match for call to ‘(Derived) (std::string)’, but if I change derived class into below,

class Derived: public Base {
public:
    using Base::operator();
    void operator()(double d) override {
        std::cout << "derived double: "<< d << std::endl;
    }
};

The code will compile and works fine, I wonder why is this the case, as I am under the impression that all the Base class public function will be in Derived?

tesla1060
  • 2,621
  • 6
  • 31
  • 43
  • Because in **first case** `void Derived::operator()(double)` overrides `void Base::operator()(double)` but not `void Base::operator()(std::string)`. While in the **second case** you're explicitly bringing both of the Base's overloads into the `Derived` class so that now the `string` version is also there in the derived class. – Jason Jan 24 '23 at 10:04
  • There might be a better duplicate, but it has to do with how name lookups work. – ChrisMM Jan 24 '23 at 10:05
  • One function shadows the other. The reason is probably to make derived classes more resistant to bases suddenly adding new methods with the same name. – HolyBlackCat Jan 24 '23 at 10:05
  • 1
    Name lookup happens **before** overload resolution. Name lookup finds `Derived::operator()(double)` (and nothing else). Overload resolution then fails. Those are the rules, the methods in `Base` are never considered. That they are public is irrelevant. – john Jan 24 '23 at 10:07
  • title: "c++ why must use using keyword in base class" its in the derived not in the base class – 463035818_is_not_an_ai Jan 24 '23 at 10:37

1 Answers1

1

In the second case you're explicitly bringing both of the Base's overloads into the Derived class so that now the string version is also there in the derived class. This means that here the lookup finds a string parameter version that can be used and so this succeeds.

On the other hand, in the first case there the lookup finds the void Derived::operator()(double) and stops looking any further. And since there is no string version, this gives the mentioned error.

Jason
  • 36,170
  • 5
  • 26
  • 60