Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling overloaded function with floating point literal yields 'ambiguos' error [duplicate]

When compiling the following code:

#include <iostream>
using namespace std;

void print(int i){
    cout << i << endl;
}

void print(float i){
    cout << i << endl;
}

int main(){
    print(5);
    print(5.5)
    return 0;
}

I get the error:

call of overloaded 'print(double)' is ambiguous.

However, if I change

void print(float i){

to

void print(double i){

the code compiles. Why is that?

like image 488
OpenGLmaster1992 Avatar asked Dec 15 '22 11:12

OpenGLmaster1992


2 Answers

Try a different exercise to understand this. Removing either of the two overloads will make the program compile, although there's no identity match for the literal 5.5, a double value, it can be implicitly converted to int or float.

When both overloads are present, since 5.5 can be implicitly converted to either a int or float, both are viable. The compiler is unable to decide between the two, hence the error.

Upon making the literal a float, 5.5f, we've an identity match, the float overload and no ambiguity in decision for the compiler. Conversely, keeping the literal double, 5.5, changing the function prototype from float to double also works since this is an identity match as well.

like image 192
legends2k Avatar answered May 18 '23 16:05

legends2k


The problem is that 5.5 is of type double. Since print is overloaded, the compiler will look for the best match to find out which overload to call, a process called overload resolution. This is a quite complex set of rules, but here is what happens in your simple case:

First the compiler will check for an exact match, i.e. some void print(double); or the like.

Since this does not exist, it considers conversions. A double can be implicitly converted to both int and float, and those conversions are deemed equally good.

Thus, the compiler cannot decide which function overload it should call and complains that the call is ambiguous.

As already mentioned by others, you can fix this by either getting the input type exactly right: print(5.5f); or adding an overload that is an unambiguously better match for a double argument, like e.g.

void print (double);
void print (const double&);
template <class T>
void print (T);
like image 34
Baum mit Augen Avatar answered May 18 '23 18:05

Baum mit Augen