Me pregunto si hay una opción para deshabilitar (?) El tipo de conversión al inicializar / comparar objetos con variables de tipo específico:
class X {
//...
const bool operator<=(const long long val) const;
const bool operator<=(const char* val) const;
const X& operator=(const long long val);
const X& operator=(const char* val);
}
int main() {
X x1 = 10; //thats ok
X x2 = "123"; //ok again
X x3 = 0; //error, 0 is "valid" char*
x1 <= 0 ? true : false; //error, same reason
}
Aquí está el error: more than one operator "<=" matches these operands
¿Hay alguna manera de deshacerse de estos errores? Sé que puedo echar en main
pero desafortunadamente eso no es lo que quiero, o de hecho incluso se me permite hacer:
X x3 = (long long)0; //no no no...
También no std::string
.
Respuesta (parcial)
Por lo tanto, la parte de la asignación se puede resolver cambiando la declaración de clase, eliminando long long
Asignar y hacer constructores propios explícitos / implícitos.
// allow implicit conversion from long long, ex. X x = 13;
X(long long val)
// disable implicit conversion from const char*, now X x = 0 is ok - calls the above
explicit X(const char* val);
// allow assignment from const char as well, no confusion with 0 now
const X& operator=(const char*);
Respuestas
1 para la respuesta № 1La razón por la que la llamada es ambigua es que ambas sobrecargas tienen el mismo rango de conversión estándar, según la tabla 12 en 13.3.3.1.1 [over.ics.scs] en el estándar 14882: 2011 ISO C ++. UNA 0
literal es de tipo int
. Una conversión a long long
es una conversión integral (ver 4.7), y una conversión a const char*
es una conversión de puntero (ver 4.10).
La solución más fácil es simplemente agregar sobrecargas para int
. Usted podría simplemente llamar al long long
versión del constructor / operador apropiado al enviar el argumento a long long
, al igual que:
class X
{
public:
// ...
X(int i) : X((long long)i) { }
const X& operator=(int i) { return operator=((long long)i); }
// etc
};
Su solución parcial "funciona", aunque la segunda línea en main()
en tu ejemplo ya no se compilará. Porque una conversión de const char*
se hace explícito, ya no se le permite hacer esto:
X x = "Hi there!"; // error: no implicit conversion from const char[10] to X
X x("Hi there!"); // ok
Otra advertencia es que las operaciones con un long long
podría ser potencialmente costoso, dependiendo de su implementación de X, porque primero se debe construir una X temporal antes de realizar la asignación / comparación / etc.