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?
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.)