If you encounter something one morning and happen to see a professional addition in the afternoon, record it.
Ambiguous Call is a compilation error.
When calling the function to match the appropriate parameter list, it is found that the currently provided parameters can match multiple overloaded functions. for example:
int add(int a, int b) {
return a + b;
}
template<typename T>
T add(T a, T b) {
return a + b;
}
int main() {
add(10, 20);
add(10.5, 20.5);
add(string("10.5"), string("20.5"));
return 0;
}
Of course, the compiler will not be so stupid and will pursue the best match. int
will be called when the arguments are two add(int, int)
and will not be add(T, T)
.
However, if there are multiple best matches, then something is wrong:
long long add(int, long long) {
return 0;
}
long long add(long long, int) {
return 0;
}
int main() {
// ???
add(10, 20);
return 0;
}
For literal integers, they are completely compatible int
with long long
the type, so it is impossible to distinguish which function is to be called, because no matter which one is called, it is reasonable and there is no problem at all from the perspective of the type.
The reconstruction formed by
add(int, long long)
andadd(long long, int)
is a bit nonsense, but this is just to demonstrate the ambiguity problem and does not explore the rigor.
The best solution is to completely prevent the occurrence of this kind of function reconstruction.
Otherwise, please explicitly tell the compiler what the type of the literal value is when calling, rather than letting it guess by itself. for example:
long long add(int, long long) {
return 0;
}
long long add(long long, int) {
return 0;
}
int main() {
// ok
int a = 10;
long long b = 20;
add(a, b);
add((long long)10, 20);
add(10, (long long)20);
return 0;
}
It was found that if only one parameter type is marked int
, it will still lead to ambiguous calls. It is quite interesting. You can analyze why.
int main() {
// ???
add((int)10, 20);
add(10, (int)20);
return 0;
}
If one of the parameters is explicitly stated as int
, then according to our observation, a function with a function signature of int a, T b
or should be selected T a, int b
to achieve a match.
However , for integer literals, the default behavior is to treat themint
as Explicit annotations cannot compete for conversion priority .int
long long
int
Only if the value of another parameter whose type is not explicitly specified exceeds int
the range will it be positioned long long
to achieve a match.
Under normal circumstances, it is difficult to encounter ambiguous calls. It is difficult to write such a function casually. Just know such a term to describe this situation.
End