2009-07-24 12 views
19

Encontré una situación interesante hoy en un programa en el que inadvertidamente asigné un entero sin signo a std :: string. El compilador de VisualStudio C++ no dio ninguna advertencia o error al respecto, pero me fijé en el error cuando ejecuté el proyecto y me dio caracteres no deseados para mi cadena.¿Por qué C++ permite asignar un número entero a una cadena?

Esto es algo de lo que el código parecía:

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string = my_number; 

El siguiente código también compila bien:

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string.operator=(my_number); 

los siguientes resultados en un error:

unsigned int my_number = 1234; 
std::string my_string(my_number); 

Lo ¿está pasando? ¿Cómo es que el compilador detendrá la compilación con el último bloque de código, pero dejar que los primeros 2 bloques de código se creen?

+0

¿Cuáles son los errores del compilador? Para mí, g ++ v4.4 compila y funciona correctamente – CsTamas

+0

Lo siento, cometí un error con el 2º bloque de código: compila. El último falla con un error acerca de no tener un constructor std :: string que acepte un int sin firmar. – user55417

Respuesta

28

Porque la secuencia se puede asignar desde char, y int es implícitamente convertible en char.

+0

¿Cómo es que el int no está implícitamente emitido en los últimos 2 bloques? ¿Qué quiere decir con que no puedo llamar a operator = explícitamente? Porque los siguientes trabajos: my_string.operator = ("hello world"); – user55417

+0

¿No es 'my_string.operator = (my_number)' una llamada explícita a 'operator ='? ¿Qué estoy malentendiendo aquí? – sbi

+0

"¿Cómo es que el int no se convierte implícitamente en los últimos 2 bloques?" Porque aunque 1234 cabe en 16 bits, y puede haber un char, no todas las int sin firmar caben en 16 bits. Tan pronto como especificó un tipo con un rango mayor que un char, detuvo el compilador de convertir implícitamente el valor en un char. –

20

clase El std :: string tiene la siguiente operador de asignación definida:

string& operator=(char ch); 

Este operador es invocado por conversión implícita de unsigned int a char.

En el tercer caso, se utiliza un constructor explícito para crear instancias de un std::string, ninguno de los constructores disponibles puede aceptar una unsigned int, o utilizar la conversión implícita de unsigned int:

string(); 
string(const string& s); 
string(size_type length, const char& ch); 
string(const char* str); 
string(const char* str, size_type length); 
string(const string& str, size_type index, size_type length); 
string(input_iterator start, input_iterator end); 
+3

"los operadores no pueden invocarse utilizando la sintaxis de llamada funcional". 13.5 (4) en el estándar C++ dice que pueden. –

+0

"los operadores no pueden ser invocados usando la sintaxis de llamada funcional" Eso es completamente incorrecto. – sbi

+1

Es una pena, porque la respuesta aceptada cometió el mismo error al principio, pero se votó de todos modos y luego se corrigió, mientras que esta respuesta es mucho mejor y se votó a favor. Voy a votar por esto si se soluciona. –

2

En definitiva, es el operador = (char ch) call - mi depurador entró en eso. Y mi MS VS 2005 compila los siguientes sin error.

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string = my_number; 
my_string.operator=(my_number); 
0

me puede explicar el primer y tercer situaciones:

my_string = 1234; 

Esto funciona porque la cadena ha anulado operador = (char). En realidad, está asignando un carácter (con desbordamiento de datos) a la cadena. No sé por qué el segundo caso da como resultado un error de compilación. Probé el código con GCC y compila.

std::string my_string(1234); 

no funcionará, porque no hay ningún constructor de cadenas que tome un argumento char o int.

Cuestiones relacionadas