c++ - concatenar - Anexar int a std:: string
append c (4)
La forma correcta de agregar a su string
sería
std::string s;
s += std::to_string(2);
s = s + std::to_string(2);
Intenté dos formas diferentes de anexar un int
a std::string
, y para mi sorpresa, obtuve resultados diferentes:
#include <string>
int main()
{
std::string s;
s += 2; // compiles correctly
s = s + 2; // compiler error
return 0;
}
¿Por qué compila y funciona correctamente cuando uso el operador +=
, pero falla cuando uso el operador +
?
No creo que la pregunta sea como ¿Cómo concatenar un std :: string y un int?
En esa pregunta, ninguna respuesta usa +=
operator. Y la diferencia entre +=
y +
operator de std::string
es la clave para resolver mi duda.
Francamente, la pregunta es un buen ejemplo para explicar por qué C ++ es tan difícil de dominar.
Si bien la respuesta @CoryKramer le da la forma correcta de agregar un entero a una cadena, no explica por qué la instrucción s = s + 2
no se compila.
La diferencia entre las dos instrucciones es que en el primero se utiliza el operador std::string
+ s mientras que en la segunda instrucción, el compilador intenta convertir 2
en una cadena.
No hay conversión implícita entre int
y std::string
. sin embargo, puede convertir un int
en char
, por lo que s += 2
funciona.
s += 2;
no está haciendo lo que crees que está haciendo. Llama al operador +=
sobrecargado a un char
. No agrega el carácter ''2''
, sino el carácter con valor 2, y el resultado dependerá de la codificación utilizada en su plataforma.
No hay una sobrecarga del operador definida para permitir que s + 2
compile 1 . De ahí el error.
La solución en ambos casos es usar std::to_string(2)
lugar de int
literal 2.
1 Esencialmente, la razón es porque operator+=
no es una función de plantilla, sino std::operator+
is, y la resolución de sobrecarga favorecerá una función que no sea de plantilla sobre una plantilla.
TL; DR operator+=
es una función miembro de class string
en class string
, mientras que operator+
es una función de plantilla.
La template<typename CharT> basic_string<CharT>
clase estándar template<typename CharT> basic_string<CharT>
tiene una función sobrecargada basic_string& operator+=(CharT)
, y string es solo basic_string<char>
.
Como los valores que se ajustan a un tipo más bajo se pueden convertir automáticamente en ese tipo, en la expresión s += 2
, el 2 no se trata como int
, sino como char
. Tiene exactamente el mismo efecto que s += ''/x02''
. Se anexa un carácter con código ASCII 2 (STX), no el carácter ''2'' (con valor ASCII 50 o 0x32).
Sin embargo, la cadena no tiene una función de miembro sobrecargada como string operator+(int)
, s + 2
no es una expresión válida, por lo que arroja un error durante la compilación. (Más abajo)
Puede usar operador + función en cadena de las siguientes maneras:
s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only
Para las personas preocupadas acerca de por qué 2 no se convierte automáticamente en char
con operator+
,
template <typename CharT>
basic_string<CharT>
operator+(const basic_string<CharT>& lhs, CharT rhs);
Lo anterior es el prototipo [nota] para el operador más en s + 2
, y debido a que es una función de plantilla, requiere una implementación tanto del operator+<char>
como del operator+<int>
, lo cual es conflictivo. Para obtener detalles, consulte ¿Por qué no se aplica downcasting automático a las funciones de la plantilla?
Mientras tanto, el prototipo de operator+=
es:
template <typename CharT>
class basic_string{
basic_string&
operator+=(CharT _c);
};
Verá, no hay plantilla aquí (es una función miembro de la clase), por lo que el compilador deduce ese tipo CharT es char
de la implementación de clase, y int(2)
se convierte automáticamente en char(2)
.
Nota: El código innecesario se elimina cuando se copia desde C ++ estándar. Eso incluye typename 2 y 3 (Traits and Allocator) para la clase de plantilla "basic_string" y guiones bajos innecesarios para mejorar la legibilidad.