0

The following code:

class Base1
{
public:
    void go() {}
};

class Base2
{
public:
    void go(int a) {}
};

class Derived : public Base1, public Base2 {};

int main()
{
    Derived d;

    d.go(3);

    return 0;
}

will give an error during compilation:

g++ -o a a.cc
a.cc: In function ‘int main()’:
a.cc:19:7: error: request for member ‘go’ is ambiguous
a.cc:10:10: error: candidates are: void Base2::go(int)
a.cc:4:10: error:                 void Base1::go()
make: *** [a] Error 1

It's easy to see the prototypes in base classes are different. But why cannot the compiler detect this and automatically choose the matching one?

Cyker
  • 9,946
  • 8
  • 65
  • 93

1 Answers1

4

Function overloading is not allowed across class boundaries. You can fix this by writing the Derived class like so -

class Derived : public Base1, public Base2
{
public:
    using Base1::go;
    using Base2::go;
};
Superman
  • 3,027
  • 1
  • 15
  • 10
  • Thanks! But what's the reason for forbidding function overloading across class boundaries? Is it because this will exert heavy burden on the compiler? – Cyker Jun 08 '12 at 06:42
  • @cyker: actually, the compiler did look into both, however think about you the developer; it is challenging in a deep and complex hierarchy to have to search the entire hierarchy for all occurrences of a possibly overloaded function. With this restriction, it works naturally if there is no overload (so you can stop searching at the first function with that name) and otherwise you know exactly where to look for them. Imagine if `Derived` had a hundred base classes, knowing the 2 you have too look at is quite helpful :) – Matthieu M. Jun 08 '12 at 07:05
  • The scope of the function is in the class it belongs to. So that is where the compiler will check for overloads. Otherwise it would need to look through all classes, all namespaces, all includes and you can see it can lead to unexpected and unwanted behavior. – Superman Jun 08 '12 at 07:12