1
#include <iostream>

using namespace std;

void somefunc(int a)
{
    cout<<"somefunc1";
}

void somefunc(int &b)
{
    cout<<"somefunc2";
}

int main()
{

    // case 1 
    somefunc(10); // works fine and prints somefunc1

   //case2
    int b=10;
    somefunc(b); // generates compiler error that overloading is ambiguous 

   return 0;
}

In main() if I pass a constant (say 10) program compiles and runs and prints "somefunc1", but when I pass a variable (b in this case) compiler generates an error that overloading is ambiguous.

I don't understand how is it working internally. Please help!!

4
  • 3
    That's because binding to a reference is an "exact match", so the overloads are ambiguous. Commented Dec 20, 2016 at 19:39
  • 1
    What you refer to as a "constant" is called an "integer literal". Passing a constant (e.g. const int c = 10;) would produce a different result. Why passing c is different from passing b is left as an exercise to the reader. Commented Dec 20, 2016 at 19:42
  • 1
    @IInspectable: Your constant would also work fine. Commented Dec 20, 2016 at 19:43
  • @KerrekSB: Yes, of course. A bit sloppy on the wording there. Sorry for the confusion. Commented Dec 20, 2016 at 19:49

1 Answer 1

4

The rules for overload resolution are a bit complicated. This is a simplification, applicable to this particular example.

The first step the compiler goes through is finding the "overload set", that is, the set of functions that can be called with the argument. For somefunc(10), only somefunc(int) can be called; somefunc(int&) cannot be called, because 10, being a constant, can't be passed by (non-const) reference. So there's only one function in the overload set, and that's the one that gets called.

For somefunc(b), both functions can be called. So the overload set has two functions, somefunc(int) and somefunc(int&). Now the compiler has to determine which function is the "best match" for the argument 10. And the rule is that int and int& both provide an "exact match", so the rules do not prefer one over the other, and the call is ambiguous.

If the second version of the function had been somefunc(const int&) instead of somefunc(int&) the call somefunc(10) would also be ambiguous.

Sign up to request clarification or add additional context in comments.

5 Comments

If such is the case then overloading should not be allowed for such case.
@Swapnil: If you want that to happen, you need to work out a paper, and contact the WG21.
@Swapnil - which case are you referring to?
@PeteBecker The main question is "What is the use of function overloading with argument passed by value and reference?" For such cases compiler should throw error and should not wait to get ambiguous error.
@Swapnil - somefunc(int) and somefunc(int&) are valid, distinguishable overloads. somefunc(int) and somefunc(const int&) aren't, but consider that they may well be declared in completely separate headers for two completely separate libraries. If you don't call the function, there's no issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.