2009-10-28 25 views
9

Tengo problemas para sobrecargar métodos en C++. Como un ejemplo del problema, tengo una clase con una cantidad de métodos sobrecargados, y cada método tiene un parámetro con un tipo de datos diferente. Mi pregunta: ¿hay algún orden en particular en la clase en que deberían aparecer estos métodos, para asegurarse de llamar al método correcto según el tipo de datos de sus parámetros?Función/Sobrecarga del método C++: ¿Confusión del tipo de datos?

class SomeClass{ 
    public: 
    ... 
    void Method(bool paramater); 
    void Method(std::string paramater); 
    void Method(uint64_t paramater); 
    void Method(int64_t paramater); 
    void Method(uint8_t paramater); 
    void Method(int8_t paramater); 
    void Method(float paramater); 
    void Method(double paramater); 
    void Method(ClassXYZ paramater); 
} 

Noté que había un problema porque cuando se ejecuta:

Method("string"); 

que estaba llamando:

Method(bool paramater); 

Respuesta

5

La cadena literal "string" tiene tipo const char[], que se puede convertir en bool implícitamente. Este es el mejor candidato de conversión para una de sus funciones sobrecargadas, aunque probablemente no sea la más útil.

Si su intención era tener cadenas literales ser manejados por la sobrecarga de tomar una std::string, entonces es necesario agregar una sobrecarga de tomar una const char* y hacer que la aplicación llama a la versión std::string.

+0

ESTO ES COMPLETAMENTE MOLESTO. Estas reglas de resolución son insuficientes para lograr un concepto tan básico. Tal vez el enfoque intuitivo OP "por orden de declaración" haría un mejor trabajo. –

4

La orden no tiene importancia. El problema aquí es que cuando invoca

Method("string"); 

está pasando un const char []. Esto se convertirá a bool implícitamente. Lo que quiere hacer es pasar una std :: string explícitamente:

Method(std::string("string")); 
+0

No echar; ¡construir! std :: string ("cadena") (o hacer una sobrecarga para chatear * como se dijo anteriormente) –

+0

Por supuesto; editado, gracias. – Tomas

23

La orden no hace la diferencia. El método para llamar se selecciona al analizar los tipos de argumentos y hacerlos coincidir con los tipos de parámetros. En caso de que no haya una coincidencia exacta, se selecciona el mejor método de coincidencia. En su caso, es el método bool.

Proporciona un argumento del tipo const char[7]. De acuerdo con las reglas de sobrecarga de C++, la mejor ruta aquí es dejar const char[7] decaer a const char * y luego convertirlo a bool usando una conversión estándar. La ruta con la conversión a std::string se considera peor, ya que implicaría una conversión definida por el usuario de const char * a std::string. En general, las conversiones definidas por el usuario pierden el proceso de resolución de sobrecarga en conversiones estándar. Esto es lo que sucede en tu caso también.

Si se necesita la versión std::string ser llamado aquí, proporcionan una sobrecarga explícita para const char * tipo y delegar la llamada a la versión std::string convirtiendo el argumento para std::string tipo explícitamente

void Method(const char *paramater /* sic! */) 
{ 
    Method(std::string(paramater)); 
} 
+1

under-defined -> definido por el usuario? – jalf

+0

Solucionado. Gracias. – AnT

1

Como Charles ya se ha señalado, esto sucede debido a una conversión implícita no deseada. Si se quiere evitar que, utilizar un constructor std :: string: Method(std::string("string")); o echarlo a std :: string:

Method(static_cast<std::string>("string")); 

Sin embargo, el orden de las declaraciones no es importante.También verifique la ortografía de la palabra "parámetro";)

1

Además del problema de cadena, hay otro. int64_t e int8_t son (generalmente) typedefs. Como los typedefs son solo alias, pueden referirse al mismo tipo, en cuyo caso la sobrecarga no funcionará. Pero esto es bastante improbable en tu caso. Solo quería mencionarlo.

2

No respondiendo a su pregunta pero, solo por curiosidad, ¿hay algún motivo oculto para no usar un método de plantilla en lugar de definir una versión de sobrecarga para cada tipo?

class SomeClass 
{ 
    public: 
    ... 
    template <typename T> 
    void Method(T paramater); 
}; 
+0

Esto es bueno porque deshabilitará las conversiones automáticas que comienzan a ponerse raras. También puede definir su método solo para las pocas especializaciones que pretende respaldar. –

1

Se puede añadir una explict palabra clave a fin de tener el argumento previsto.