Llamada ambigua

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. intSe 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 intcon long longel 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)y add(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 bo T a, int bpara lograr una coincidencia.

Sin embargo , para los literales enteros, un comportamiento predeterminado es tratarlos intcomo Las anotaciones explícitas no pueden competir por la prioridad de conversión .intlong long

intSólo si el valor de otro parámetro cuyo tipo no se especifica explícitamente excede intel rango, se posicionará long longpara 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

Supongo que te gusta

Origin blog.csdn.net/qq_49661519/article/details/125249427
Recomendado
Clasificación