c++ overloading ambiguous-call

c++ - siendo literal `0` un candidato válido para int y const string y sobrecargas causa una llamada ambigua



overloading ambiguous-call (2)

Mi pregunta es por qué el compilador solo se quejó cuando el parámetro era 0.

Porque 0 no es solo un literal entero, sino que también es un literal de puntero nulo. 1 no es un puntero literal nulo, por lo que no hay ambigüedad.

La ambigüedad surge del constructor de conversión implícito de std::string que acepta un puntero a un carácter como argumento.

Ahora, la conversión de identidad de int a int sería preferible a la conversión de puntero a cadena, pero hay otro argumento que implica una conversión: el argumento objeto implícito. En un caso, la conversión es de CppSyntaxA& a CppSyntaxA& mientras que en otro caso es de CppSyntaxA& a const CppSyntaxA& .

Por lo tanto, se prefiere una sobrecarga debido a un argumento, y la otra sobrecarga se prefiere debido a otro argumento y, por lo tanto, no existe una sobrecarga inequívocamente preferida.

El problema se solucionará haciendo que ambas funciones consten.

Si ambas sobrecargas están calificadas por const , entonces la secuencia de conversión implícita del argumento del objeto es idéntica y, por lo tanto, una de las sobrecargas es inequívocamente preferida.

He arreglado un error recientemente.

En el siguiente código, una de las funciones sobrecargadas era const y la otra no. El problema se solucionará haciendo que ambas funciones consten.

Mi pregunta es por qué el compilador solo se quejó cuando el parámetro era 0.

#include <iostream> #include <string> class CppSyntaxA { public: void f(int i = 0) const { i++; } void f(const std::string&){} }; int main() { CppSyntaxA a; a.f(1); // OK //a.f(0); //error C2666: ''CppSyntaxA::f'': 2 overloads have similar conversions return 0; }


0 es especial en C ++. Un puntero nulo tiene el valor de 0 por lo que C ++ permitirá la conversión de 0 a un tipo de puntero. Eso significa que cuando llamas

a.f(0);

Podría estar llamando a void f(int i = 0) const con un int con el valor de 0 , o podría llamar a void f(const std::string&) con un char* inicializado a nulo.

Normalmente, la versión int sería mejor ya que es una coincidencia exacta, pero en este caso la versión int es const , por lo que requiere "convertir" a a una const CppSyntaxA , donde la versión std::string no requiere tal conversión, pero sí requiere una conversión a char* y luego a std::string . Esto se considera un cambio suficiente en ambos casos para considerarse una conversión igual y, por lo tanto, ambiguo. Al hacer ambas funciones const o non const se solucionará el problema y se elegirá la sobrecarga int , ya que es mejor.