Why are the following overloaded function calls ambiguous?? With the compile error:
call of overloaded ‘test(long int)’ is ambiguous,candidates are: void test(A)|
void test(B)|
The code:
class A
{
public:
A(int){}
A(){}
};
class B: public A
{
public:
B(long){}
B(){}
};
void test(A a)
{
}
void test(B b)
{
}
void main()
{
test(0L);
return;
}
You got an error because overload resolution has to choose from two equally viable functions (both have user-defined conversions). Function overload resolution is a very complicated subject. For more details on the overload resolution see e.g. this recent lecture by Stephan T. Lavavej. It’s generally best to make single-argument constructors
explicit, and then to call your function with an explicit constructor argument.test(0L)is not an exact match to any overload because there is no overloadtest(long). The two overloads you provided both have user-defined conversions on their arguments, but the compiler considers them equally viable. TheAoverload has to do a standard conversion (long to int) followed by a user-defined conversion (int to A), and theBoverload a user-defined conversion (long to B). But both are implicit user-defined conversion sequences.How are these ranked? The Standard says in 13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]
These type of tie-breaking e.g. apply if A would be a derived class from B (or vice versa). But here neither conversion sequence is a subsequence of the other. Therefore they are equally viable and the compiler cannot resolve the call.
NOTE: it’s
int main(), notvoid main().