Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is ambiguity determined in the overload resolution algorithm?

I'm trying to understand the overloading resolution method.

Why is this ambiguous:

void func(double, int, int, double) {} void func(int, double, double, double) {}  void main() {     func(1, 2, 3, 4); } 

but this isn't?

void func(int, int, int, double) {} void func(int, double, double, double) {}  void main() {     func(1, 2, 3, 4); } 

In the first case there are 2 exact parameters matches and 2 conversions against 1 exact match and 3 conversions, and in the second case there are 3 exact matches and 1 conversion against 1 exact matches and 3 conversions.

So why is one ambiguous and one is not? What is the logic here?

like image 579
Ana M Avatar asked Mar 17 '15 03:03

Ana M


People also ask

What is ambiguity in function overloading?

When the compiler is unable to decide which function it should invoke first among the overloaded functions, this situation is known as function overloading ambiguity. The compiler does not run the program if it shows ambiguity error.

How to Remove ambiguity in function overloading?

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.

Why will an ambiguity error arise if a default value is given to an argument of an overloaded function?

Function Overloading and float in C++ If the compiler can not choose a function amongst two or more overloaded functions, the situation is -” Ambiguity in Function Overloading”. The reason behind the ambiguity in above code is that the floating literals 3.5 and 5.6 are actually treated as double by the compiler.

How are function calls matched with overloaded functions?

The compiler selects which overloaded function to invoke based on the best match among the function declarations in the current scope to the arguments supplied in the function call. If a suitable function is found, that function is called. "Suitable" in this context means either: An exact match was found.


1 Answers

The overload resolution rules only define a partial order on the set of all matches - if an overload F1 is not a better match than F2, it does not imply that F2 is a better match than F1. The exact partial order can be thought of as comparing two points in k dimensions, where the number of arguments is k. Lets define this partial order on points in k-dim space - (x_1, x_2,..., x_k) < (y_1, y_2,..., y_k) if x_i <= y_i for all i and x_j < y_j for at least one j. This is exactly the partial order on candidate non-template functions defined by the standard.

Lets look at your examples :

void func(double, int,    int,    double) {}                   vvv     vvv       vvv                  better  better    equal void func(int,    double, double, double) {}           vvv                       vvv          better                    equal 

So neither overload is strictly better than the other.

In your second example:

void func(int,   int,   int,   double) {}           vvv    vvv    vvv     vvv          equal  better better  equal void func(int, double, double, double) {}           vvv          equal 

Now, the first overload is better than the second in all but one argument AND is never worse than the second. Thus, there is no ambiguity - the partial order does indeed declare the first one better.

(The above description does not consider function templates. You can find more details at cppreference.)

like image 149
Pradhan Avatar answered Oct 04 '22 10:10

Pradhan