Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ overload resolution [duplicate]

Given the following example, why do I have to explicitly use the statement b->A::DoSomething() rather than just b->DoSomething()?

Shouldn't the compiler's overload resolution figure out which method I'm talking about?

I'm using Microsoft VS 2005. (Note: using virtual doesn't help in this case.)

class A {   public:     int DoSomething() {return 0;}; };  class B : public A {   public:     int DoSomething(int x) {return 1;}; };  int main() {   B* b = new B();   b->A::DoSomething();    //Why this?   //b->DoSomething();    //Why not this? (Gives compiler error.)   delete b;   return 0; } 
like image 579
Abe Avatar asked Sep 16 '08 13:09

Abe


People also ask

How do you fix an ambiguous call to overloaded function?

There are two ways to resolve this ambiguity: Typecast char to float. Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.

What is overload resolution?

The process of selecting the most appropriate overloaded function or operator is called overload resolution. Suppose that f is an overloaded function name. When you call the overloaded function f() , the compiler creates a set of candidate functions.

Can you function overload in C?

Function overloading is a feature of Object Oriented programming languages like Java and C++. As we know, C is not an Object Oriented programming language. Therefore, C does not support function overloading.

How function calls are matched with overloaded functions?

The process of matching function calls to a specific overloaded function is called overload resolution. Just because there is no exact match here doesn't mean a match can't be found -- after all, a char or long can be implicitly type converted to an int or a double .


2 Answers

The two “overloads” aren't in the same scope. By default, the compiler only considers the smallest possible name scope until it finds a name match. Argument matching is done afterwards. In your case this means that the compiler sees B::DoSomething. It then tries to match the argument list, which fails.

One solution would be to pull down the overload from A into B's scope:

class B : public A { public:     using A::DoSomething;     // … } 
like image 164
Konrad Rudolph Avatar answered Oct 11 '22 10:10

Konrad Rudolph


Overload resolution is one of the ugliest parts of C++

Basically the compiler finds a name match "DoSomething(int)" in the scope of B, sees the parameters don't match, and stops with an error.

It can be overcome by using the A::DoSomething in class B

class A   {     public:       int DoSomething() {return 0;} };    class B : public A   {     public:       using A::DoSomething;     int DoSomething(int x) {return 1;}  };      int main(int argc, char** argv) {   B* b = new B();     // b->A::DoSomething();    // still works, but...   b->DoSomething();    // works now too   delete b;     return 0; } 
like image 30
Pieter Avatar answered Oct 11 '22 11:10

Pieter