0

Why this code snippet does not compile if there is a member method named Derived::foo(int),

#include <string>

class Base
{
public:
    int foo(int a, double b){return 0;}
    int foo(std::string a, double b){return 0;}
};

class Derived:public Base
{
public:
    int foo(int a){return 0;}

    int do_sth()
    {
        foo(2, 3.5);

        return 0;
    }
};

int main()
{
}

,whereas the code snippet works below well when commenting out the said function.

#include <string>

class Base
{
public:
    int foo(int a, double b){return 0;}
    int foo(std::string a, double b){return 0;}
};

class Derived:public Base
{
public:
    //int foo(int a){return 0;}

    int do_sth()
    {
        foo(2, 3.5);

        return 0;
    }
};

int main()
{
}

Here is what the compiler complains about the former code snippet:

<source>: In member function 'int Derived::do_sth()':
<source>:17:12: error: no matching function for call to 'Derived::foo(int, double)'
   17 |         foo(2, 3.5);
      |         ~~~^~~~~~~~
<source>:13:9: note: candidate: 'int Derived::foo(int)'
   13 |     int foo(int a){return 0;}
      |         ^~~
<source>:13:9: note:   candidate expects 1 argument, 2 provided

I think foo(2, 3.5); does exactly match the Base::foo(int, double).It's amazing that the compiler complains about the former code snippet.

But since the compiler is almost always right, so I must miss something. Could somebody shed some light on this matter?

John
  • 2,963
  • 11
  • 33
  • You should mark the function with `virtual` – Autumnal_Joy Jun 16 '22 at 04:54
  • 2
    @Autumnal_Joy, Uh, no that is not the issue here. – Avi Berger Jun 16 '22 at 04:55
  • @Autumnal_Joy Mark the ***functions*** whose name is `foo` with `virtual`? – John Jun 16 '22 at 04:55
  • You've hit a nasty issue in C++. It does not have anything to do with virtual, but does relate to inheritance & overloaded functions. The member function in the derived class hides the same named overloads in the base class. There is a solution I'm trying to double check - its been awhile since I've looked at this. – Avi Berger Jun 16 '22 at 05:03
  • Adding `using Base::foo;` inside of Derived should prevent the other overloads from being hidden. I haven't found a good reference for this, but there should be a number around. – Avi Berger Jun 16 '22 at 05:11
  • OK, there are multiple duplicate questions: [Why. .. hide other overloads...?](https://stackoverflow.com/q/1628768/631266) and [Function with same name but different signature in derived class](https://stackoverflow.com/q/411103/631266) – Avi Berger Jun 16 '22 at 05:21

0 Answers0