10

I have this code:

#include <iostream>
#include <string>

using namespace std;

class A {
    public: void Print(int i) {cout<<i;}
};

class B : public A {
    public: void Print(string s) {cout<<s;}
};

int main() {
    B bInstance;
    bInstance.Print(1);
    return 0;
}

This gives me an error:

error: invalid conversion from 'int' to 'const char*' [-fpermissive]

meaning it is trying to call B's Print without considering the inherited overload. But, A's Print should be callable by a B instance. In fact, if I change the call to

bInstance.A::Print(1);

then it compiles without any errors, but I wanted to avoid having to write the class scope operator each time. Is there a way to tell the compiler I am trying to call the base class's overload of the function?

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
Mic
  • 409
  • 1
  • 4
  • 8
  • 2
    Overload resolution is done before searching `A` because it found something in `B`. Use a `using` statement to bring `A`'s in and have it participate in overload resolution. – chris Mar 21 '13 at 19:40
  • If I may humbly suggest that the usefulness of overloading is sometimes somewhat overrated. Consider using distinct names instead, such as `void printInt( int i );` and `void printString( string s );` – bobobobo Mar 21 '13 at 19:42

1 Answers1

14

The Print() member function in your subclass hides the member function Print() of the superclass. Therefore, the compiler will not see A::Print() and will try to invoke B::Print(), complaining that an int could not be converted into a string.

To bring A::Print() into the overload set, you can introduce a using declaration:

class A {
public: 
    void Print(int i) {cout<<i;}
};

class B : public A {
public:
    using A::Print;
//  ^^^^^^^^^^^^^^^
    void Print(string s) {cout<<s;}
};

Here is a live example of your code working after the necessary modifications.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Added that line, it now gives 'error: void A::Print(int) is inaccessible'. – Mic Mar 21 '13 at 19:46
  • 1
    @Mic, Put it in the `public:` part of `B`. I'm guessing you added it before your `public: void Print(string s) {cout< – chris Mar 21 '13 at 19:48
  • I didn't notice the 'public' part of the 'using A::Print' statement, your answer has been clear and accurate, thank you! – Mic Mar 21 '13 at 19:51
  • Link broken with the live example. Good example though. – vmonteco Jan 08 '16 at 15:07