Estou lendo C ++ acelerado por Koenig. Ele escreve que "a nova idéia é que podemos usar + para concatenar uma string e uma literal de string - ou, nesse caso, duas strings (mas não duas literais).
Tudo bem, isso faz sentido, suponho. Agora, em dois exercícios separados, destinados a esclarecer isso.
As seguintes definições são válidas?
const string hello = "Hello";
const string message = hello + ",world" + "!";
Agora, tentei executar o procedimento acima e funcionou! Então eu fiquei feliz.
Então eu tentei fazer o próximo exercício;
const string exclam = "!";
const string message = "Hello" + ",world" + exclam;
Isso não funcionou. Agora eu entendo que isso tem algo a ver com o fato de que você não pode concatenar dois literais de seqüência de caracteres, mas não entendo a diferença semântica entre o motivo pelo qual consegui fazer o primeiro exemplo funcionar (não é ", mundo" e "! "literais de duas strings? Isso não deveria ter funcionado?), mas não o segundo.
const string message = "Hello" ",world" + exclam
(por exemplo, omitir o primeiro+
) deve funcionar bem."Hello" + ", world!"
quando você pode fazer"Hello, world!"
. Como de costume, o C ++ tem uma solução simples e impressionante para um problema percebido. :-)"Hello" ", world!"
(sem o+
). Há uma série de reclamações que se pode fazer sobre C ++, mas não acho que o tratamento aqui seja um deles. É exatamente a mesma coisa que se você escrevesse1 / 3 + 1.5
, e reclamou porque a divisão era divisão integral. Para o bem ou para o mal, é assim que a maioria dos idiomas funciona."hello" " world" == "hello world"
é útil se você precisar escrever uma string longa e não desejar que ela saia da janela ou que esteja dentro de alguma restrição de comprimento de linha. Ou se uma das cadeias for definida em uma macro.Respostas:
O
+
operador tem associatividade da esquerda para a direita, portanto a expressão entre parênteses equivalente é:Como você pode ver, as duas strings são literais
"Hello"
e",world"
são "adicionadas" primeiro, daí o erro.Uma das duas primeiras seqüências de caracteres concatenadas deve ser um
std::string
objeto:Como alternativa, você pode forçar o segundo
+
a ser avaliado primeiro entre parênteses à parte da expressão:Faz sentido que o seu primeiro exemplo (
hello + ",world" + "!"
) funcione porque ostd::string
(hello
) é um dos argumentos à esquerda+
. Isso+
é avaliado, o resultado é umstd::string
objeto com a sequência concatenada e o resultadostd::string
é concatenado com o"!"
.Quanto ao motivo pelo qual você não pode concatenar dois literais de string usando
+
, é porque um literal de string é apenas uma matriz de caracteres (umconst char [N]
ondeN
é o comprimento da string mais um, para o terminador nulo). Quando você usa uma matriz na maioria dos contextos, ela é convertida em um ponteiro para seu elemento inicial.Então, quando você tenta fazer
"Hello" + ",world"
, o que você realmente está tentando fazer é adicionar doisconst char*
s juntos, o que não é possível (o que significaria adicionar dois ponteiros?) E, se fosse, não faria o que você faria. Queria fazer.Observe que você pode concatenar literais de string colocando-os um ao lado do outro; por exemplo, os dois seguintes são equivalentes:
Isso é útil se você tiver uma literal de cadeia longa que deseja dividir em várias linhas. Eles precisam ser literais de string: isso não funcionará com
const char*
ponteiros ouconst char[N]
matrizes.fonte
const string message = "Hello" + (",world"+exclam);
também funcionará, devido a parênteses explícitos (isso é uma palavra?).const string message = ((hello + ",world") + "!");
"Hello" ",world"
sintaxe é útil não apenas para quebrar em várias linhas, mas também quando uma das cadeias literais é uma macro (ou mesmo ambas). Em seguida, a concatenação acontece em tempo de compilação.Você deve sempre prestar atenção aos tipos .
Embora todos pareçam cordas
"Hello"
e",world"
sejam literais .E no seu exemplo,
exclam
é umstd::string
objeto.O C ++ possui uma sobrecarga de operador que pega um
std::string
objeto e adiciona outra string a ele. Quando você concatena umstd::string
objeto com um literal, ele cria a conversão apropriada para o literal.Mas se você tentar concatenar dois literais, o compilador não poderá encontrar um operador que use dois literais.
fonte
std::string
com outrostd::string
, uma matriz de caracteres ou um único caractere.Seu segundo exemplo não funciona porque não há
operator +
dois literais de seqüência de caracteres. Observe que uma string literal não é do tipostring
, mas é do tipoconst char *
. Seu segundo exemplo funcionará se você o revisar assim:fonte
Desde o C ++ 14, você pode usar dois literais de cadeias reais :
ou
fonte
No caso 1, devido à ordem das operações, você obtém:
(olá + ", mundo") + "!" que resolve Olá! "!" e finalmente olá
No caso 2, como James observou, você obtém:
("Hello" + ", world") + exclam, que é a concat dos literais de 2 strings.
Espero que esteja claro :)
fonte
A diferença entre uma string (ou, para ser mais preciso
std::string
) e um literal de caractere é que, para a última, não há um+
operador definido. É por isso que o segundo exemplo falha.No primeiro caso, o compilador pode encontrar um adequado,
operator+
com o primeiro argumento sendo umstring
e o segundo um caractere literal (const char*
), para que ele seja usado. O resultado dessa operação é novamente astring
, por isso repete o mesmo truque ao adicionar"!"
a ela.fonte