number - concatenate string c++
Concatenar dos literales de cadena (5)
En el caso 1, debido al orden de las operaciones obtienes:
(hola + ", mundo") + "!" que resuelve hello + "!" y finalmente para saludar
En el caso 2, como señaló James, obtienes:
("Hello" + ", world") + exclam que es el concat de 2 cadenas literales.
Espero que esté claro :)
Soy muy nuevo en programación, y estoy leyendo Accelerated C ++ por Koenig. De todos modos, estoy aprendiendo acerca de las cadenas y escribe que "la nueva idea es que podemos usar + para concatenar una cadena y un literal de cadena - o, para el caso, dos cadenas (pero no dos literales de cadena).
Bien, esto tiene sentido, supongo. Ahora en dos ejercicios separados destinados a iluminar esto.
¿Son válidas las siguientes definiciones?
const string hello = "Hello";
const string message = hello + ",world" + "!";
¡Ahora, traté de ejecutar lo anterior y funcionó! Entonces yo estaba feliz
Luego traté de hacer el siguiente ejercicio;
const string exclam = "!";
const string message = "Hello" + ",world" + exclam;
Esto no funcionó. Ahora entiendo que tiene algo que ver con el hecho de que no se pueden concatenar dos literales de cadenas, pero no entiendo la diferencia semántica entre el motivo por el que logré que funcione el primer ejemplo (¡no es "mundo" ni "!" "¿dos literales de cadenas? ¿No debería haber funcionado esto?) pero no el segundo.
¡Gracias!
La diferencia entre una cadena (o para ser precisos, std::string
) y un carácter literal es que, para este último, no hay ningún operador definido. Esta es la razón por la cual el segundo ejemplo falla.
En el primer caso, el compilador puede encontrar un operator+
adecuado operator+
con el primer argumento como una string
y el segundo como un carácter literal ( const char*
) para que lo use. El resultado de esa operación es nuevamente una string
, por lo que repite el mismo truco al agregar "!"
lo.
Siempre debes prestar atención a los tipos .
Aunque todos parecen cadenas, "Hello"
y ",world"
son literales .
Y en tu ejemplo, exclam
es un objeto std::string
.
C ++ tiene una sobrecarga de operador que toma un objeto std::string
y le agrega otra cadena. Cuando concatenas un objeto std::string
con un literal, hará la conversión adecuada para el literal.
Pero si intenta concatenar dos literales, el compilador no podrá encontrar un operador que tome dos literales.
Su segundo ejemplo no funciona porque no hay operator +
para dos literales de cadena. Tenga en cuenta que un literal de cadena no es de tipo string
, sino que es de tipo const char *
. Su segundo ejemplo funcionará si lo revisa así:
const string message = string("Hello") + ",world" + exclam;
const string message = "Hello" + ",world" + exclam;
El operador +
tiene asociatividad de izquierda a derecha, por lo que la expresión parentesis equivalente es:
const string message = (("Hello" + ",world") + exclam);
Como puede ver, los dos literales de cadena "Hello"
y ",world"
se "agregan" primero, de ahí el error.
Una de las dos primeras cadenas que se concatenan debe ser un objeto std::string
:
const string message = string("Hello") + ",world" + exclam;
Alternativamente, puede forzar que el segundo +
sea evaluado primero entre paréntesis de esa parte de la expresión:
const string message = "Hello" + (",world" + exclam);
Tiene sentido que su primer ejemplo ( hello + ",world" + "!"
) Funcione porque std::string
( hello
) es uno de los argumentos más a la izquierda +
. Ese +
se evalúa, el resultado es un objeto std::string
con la cadena concatenada, y el std::string
resultante se concatena con el "!"
.
En cuanto a por qué no puede concatenar dos literales de cadena utilizando +
, es porque un literal de cadena es simplemente una matriz de caracteres (un const char [N]
donde N
es la longitud de la cadena más uno, para el terminador nulo). Cuando utiliza una matriz en la mayoría de los contextos, se convierte en un puntero a su elemento inicial.
Entonces, cuando intentas hacer "Hello" + ",world"
, lo que realmente intentas hacer es agregar dos const char*
s juntos, lo cual no es posible (¿qué significa agregar dos punteros?) y si lo fuera, no haría lo que usted quería que hiciera.
Tenga en cuenta que puede concatenar literales de cadena colocándolos uno al lado del otro; por ejemplo, los siguientes dos son equivalentes:
"Hello" ",world"
"Hello,world"
Esto es útil si tiene un literal de cadena larga que desea dividir en varias líneas. Sin embargo, tienen que ser literales de cadena: esto no funcionará con const char*
pointers o const char[N]
arrays.