2010-11-06 10 views
12

Considérese la clase foo con dos constructores se define así:¿Por qué hay una conversión de tipo implícita de punteros a bool en C++?

class foo 
{ 
public: 
    foo(const std::string& filename) {std::cout << "ctor 1" << std::endl;} 
    foo(const bool some_flag = false) {std::cout << "ctor 2" << std::endl;} 
}; 

una instancia de la clase con una cadena literal, y adivinar qué constructor se llama?

foo a ("/path/to/file"); 

Salida:

ctor 2

No sé ustedes, pero no me parece que el comportamiento más intuitivo en la historia de la programación. Aunque creo que hay alguna razón inteligente para ello, y me gustaría saber qué podría ser.

+2

posible duplicado de [¿Por qué el compilador elige bool sobre cadena para typecast implícito de L ""?] (Http://stackoverflow.com/questions/316181/why-does-the-compiler-choose-bool-over -string-for-implicit-typecast-of-l) – Hasturkun

+2

Sin embargo, otra pregunta similar: [Función/Método de sobrecarga C++: tipo de datos de confusión?] (http://stackoverflow.com/questions/1636181/function-method-overloading- c-data-type-confusion) – Athari

+0

Lo siento. Hice la búsqueda (ya que pensé que sería una pregunta frecuente), pero no encontré ninguna pregunta con un título que implicara que la pregunta era sobre esto. – Oystein

Respuesta

9

Es muy común en C para escribir este

void f(T* ptr) { 
    if (ptr) { 
     // ptr is not NULL 
    } 
} 

usted debe hacer un constructor const char*.

+7

Seguramente quiere decir 'if (! Ptr) return;'? :) No queremos que toda nuestra función anidada en bloque sea más de lo necesario. – GManNickG

+3

@GMan: exasperantemente, he tenido que * defender * ese tipo de declaración de devolución, porque los poderes establecidos decidieron que las declaraciones de devolución múltiple eran inherentemente confusas y difíciles de seguir, y consagraron esa creencia en los estándares de codificación. – Cascabel

+2

Me gustaría votar esto, si no recomendaría un parámetro 'char *':/ –

1

Estás confundiendo dos problemas. Una es que "blah" se puede convertir implícitamente a string y la otra es que const char* se puede convertir implícitamente en booleano. Es muy lógico ver al compilador pasar a la conversión implícita que minimiza la cantidad total de conversiones necesarias.

+0

Solo estaba dando un ejemplo que sentí que sería común encontrar: mi pregunta era ¿por qué? La conversión de tipo implícita a 'bool' ocurre con los punteros. – Oystein

2

Estás pasando un char * al constructor foo. Esto se puede convertir implícitamente en booleano (como todos los punteros) o en std :: string. Desde el punto de vista del compilador, la primera conversión es "más cercana" que la segunda porque favorece las conversiones estándar (es decir, puntero a bool) sobre las conversiones proporcionadas por el usuario (el constructor std :: string (char *)).

Cuestiones relacionadas