Si encuentra algo una mañana y ve una incorporación profesional por la tarde, regístrelo.
La llamada ambigua es un error de compilación.
Al llamar a una función para que coincida con la lista de parámetros adecuada, se descubre que los parámetros proporcionados actualmente pueden coincidir con varias funciones sobrecargadas. Por ejemplo:
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;
}
Por supuesto, el compilador no será tan estúpido y buscará la mejor combinación. int
Se llamará cuando los argumentos sean dos add(int, int)
y no se llamará add(T, T)
.
Sin embargo, si hay varias mejores coincidencias, entonces algo anda mal:
long long add(int, long long) {
return 0;
}
long long add(long long, int) {
return 0;
}
int main() {
// ???
add(10, 20);
return 0;
}
Para los enteros literales, son completamente compatibles int
con long long
el tipo, por lo que es imposible distinguir qué función se llama, porque no importa cuál se llame, es razonable y no hay ningún problema desde la perspectiva del tipo.
La reconstrucción formada por
add(int, long long)
yadd(long long, int)
es un poco absurda, pero esto es sólo para demostrar el problema de ambigüedad y no explora el rigor.
La mejor solución es evitar por completo la aparición de este tipo de reconstrucción de funciones.
De lo contrario, dígale explícitamente al compilador cuál es el tipo de valor literal al llamar, en lugar de dejar que lo adivine por sí solo. Por ejemplo:
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;
}
Se descubrió que si solo se marca un tipo de parámetro int
, seguirá dando lugar a llamadas ambiguas. Es bastante interesante. Puedes analizar por qué.
int main() {
// ???
add((int)10, 20);
add(10, (int)20);
return 0;
}
Si uno de los parámetros se indica explícitamente como int
, entonces, según nuestra observación, se debe seleccionar una función con una firma de función de int a, T b
o T a, int b
para lograr una coincidencia.
Sin embargo , para los literales enteros, un comportamiento predeterminado es tratarlos int
como Las anotaciones explícitas no pueden competir por la prioridad de conversión .int
long long
int
Sólo si el valor de otro parámetro cuyo tipo no se especifica explícitamente excede int
el rango, se posicionará long long
para lograr una coincidencia.
En circunstancias normales, es difícil encontrar llamadas ambiguas y es difícil escribir una función de este tipo de manera casual, solo conozca ese término para describir esta situación.
Fin