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.