问题
I don't understand what happens here
class A{};
class B : A {};
void func(A&, bool){}
void func(B&, double){}
int main(void)
{
B b;
A a;
bool bo;
double d;
func(b, bo);
}
When compiling, Visual 2010 gives me this error on line func(b, bo);
2 overloads have similar conversions
could be 'void func(B &,double)'
or 'void func(A &,bool)'
while trying to match the argument list '(B, bool)'
I don't understand why the bool parameter isn't enough to resolve the overload. I've seen this question, and as pointed in the accepted answer, bool should prefer the bool overload. In my case, I see that first parameter isn't enough to choose the good function, but why the second parameter doesn't solve the ambiguity?
回答1:
Overload resolution rules are even more complicated than Pete Becker wrote.
For each overload of f
, the compiler counts not only the number of parameters for which conversion is required, but the rank of conversion.
Rank 1
No conversions required
Lvalue-to-rvalue conversion
Array-to-pointer conversion
Function-to-pointer conversion
Qualification conversion
Rank 2
Integral promotions
Floating point promotions
Rank 3
Integral conversions
Floating point conversions
Floating-integral conversions
Pointer conversions
Pointer to member conversions
Boolean conversions
Assuming that all candidates are non-template functions, a function wins if and only if it has a parameter which rank is better than the rank of the same parameter in other candidates and the ranks for the other parameters are not worse.
Now let's have a look at the OP case.
func(A&, bool)
: conversion B&->A& (rank 3) for the 1st parameter, exact match (rank 1) for the 2nd parameter.func(B&, double)
: exact match (rank 1) for the 1st parameter, conversionbool->double
(rank 3) for the 2nd parameter.
Conclusion: noone wins.
回答2:
The overloading rules are a bit more complicated than you might guess. You look at each argument separately and pick the best match for that argument. Then if there is exactly one overload that provides the best match for every argument, that's the one that's called. In the example, the best match for the first argument is the second version of func
, because it requires only a conversion of B
to B&
; the other version of func
requires converting B
to B&
and then B&
to A&
. For the second argument, the first version of func
is the best match, because it requires no conversions. The first version has the best match for the second argument, but it does not have the best match for the first argument, so it is not considered. Similarly, the second version has the best match for the first argument, but it does not have the best match for the second argument, so it is not considered. Now there are no versions of func
left, and the call fails.
来源:https://stackoverflow.com/questions/12095205/vs-2010-2-overloads-have-similar-conversions