Concaténer deux littéraux de chaîne

Je suis très novice en programmation et je lis Accelerated C ++ par Koenig. Quoi qu’il en soit, j’apprends les chaînes et écrit que “la nouvelle idée est que nous pouvons utiliser + pour concaténer une chaîne et un littéral de chaîne – ou deux chaînes (mais pas deux littéraux de chaîne).

Bien, cela a du sens, je suppose. Maintenant, sur deux exercices distincts destinés à éclairer cela.

Les définitions suivantes sont-elles valides?

const ssortingng hello = "Hello"; const ssortingng message = hello + ",world" + "!"; 

Maintenant, j’ai essayé d’exécuter ce qui précède et cela a fonctionné! Donc j’étais heureux.

Ensuite, j’ai essayé de faire l’exercice suivant.

 const ssortingng exclam = "!"; const ssortingng message = "Hello" + ",world" + exclam; 

Cela n’a pas fonctionné. Maintenant je comprends que cela a quelque chose à voir avec le fait que vous ne pouvez pas concaténer deux littéraux de chaîne, mais je ne comprends pas la différence sémantique entre pourquoi j’ai réussi à faire fonctionner le premier exemple (n’est pas “, monde” et “! “deux littéraux de chaîne? Cela ne devrait-il pas avoir fonctionné?) mais pas le second.

Je vous remercie!

 const ssortingng message = "Hello" + ",world" + exclam; 

L’opérateur + a une associativité de gauche à droite, donc l’expression entre parenthèses équivalente est:

 const ssortingng message = (("Hello" + ",world") + exclam); 

Comme vous pouvez le voir, les deux littéraux de chaîne "Hello" et ",world" sont “ajoutés” en premier, d’où l’erreur.

L’une des deux premières chaînes en cours de concaténation doit être un object std::ssortingng :

 const ssortingng message = ssortingng("Hello") + ",world" + exclam; 

Vous pouvez également forcer le second + à être évalué en premier lieu en faisant entre parenthèses cette partie de l’expression:

 const ssortingng message = "Hello" + (",world" + exclam); 

Il est logique que votre premier exemple ( hello + ",world" + "!" ) Fonctionne car la std::ssortingng ( hello ) est l’un des arguments les plus à gauche + . Que + est évalué, le résultat est un object std::ssortingng avec la chaîne concaténée, et que std::ssortingng est alors concaténé avec le "!" .


Pour ce qui est de la raison pour laquelle vous ne pouvez pas concaténer deux littéraux de chaîne à l’aide de + , c’est parce qu’un littéral de chaîne n’est qu’un tableau de caractères (un caractère const char [N]N est la longueur de la chaîne plus un). Lorsque vous utilisez un tableau dans la plupart des contextes, il est converti en un pointeur sur son élément initial.

Donc, quand vous essayez de faire "Hello" + ",world" , ce que vous essayez vraiment de faire, c’est d’append deux const char* , ce qui n’est pas possible (qu’est-ce que cela signifie d’append deux pointeurs ensemble?) et si c’était ça ne ferait pas ce que vous vouliez qu’elle fasse.


Notez que vous pouvez concaténer des littéraux de chaîne en les plaçant l’un à côté de l’autre. Par exemple, les deux suivants sont équivalents:

 "Hello" ",world" "Hello,world" 

Ceci est utile si vous avez un littéral de chaîne longue que vous souhaitez diviser sur plusieurs lignes. Ils doivent cependant être des littéraux de chaîne: cela ne fonctionnera pas avec les tableaux de caractères const char* ou les tableaux const char[N] .

Vous devez toujours faire attention aux types .

Bien qu’ils semblent tous être des chaînes, "Hello" et ",world" sont des littéraux .

Et dans votre exemple, exclam est un object std::ssortingng .

C ++ a une surcharge d’opérateur qui prend un object std::ssortingng et lui ajoute une autre chaîne. Lorsque vous concaténez un object std::ssortingng avec un littéral, il fera un casting approprié pour le littéral.

Mais si vous essayez de concaténer deux littéraux, le compilateur ne pourra pas trouver un opérateur qui prend deux littéraux.

Votre deuxième exemple ne fonctionne pas car il n’y a pas d’ operator + pour deux littéraux de chaîne. Notez qu’un littéral de chaîne n’est pas de type ssortingng , mais est de type const char * . Votre deuxième exemple fonctionnera si vous le révisez comme ceci:

 const ssortingng message = ssortingng("Hello") + ",world" + exclam; 

Dans le cas 1, en raison de l’ordre des opérations, vous obtenez:

(bonjour + “, monde”) + “!” qui se résume à hello + “!” et enfin bonjour

Dans le cas 2, comme l’a noté James, vous obtenez:

(“Bonjour” + “, monde”) + exclam qui est le concat de 2 littéraux de chaîne.

J’espère que c’est clair 🙂

La différence entre une chaîne (ou pour être précis, std::ssortingng ) et un caractère littéral est que pour ce dernier il n’y a pas d’opérateur + défini. C’est pourquoi le deuxième exemple échoue.

Dans le premier cas, le compilateur peut trouver un operator+ approprié operator+ le premier argument étant une ssortingng et le second un caractère littéral ( const char* ). Le résultat de cette opération est encore une ssortingng , donc elle répète le même tour en ajoutant "!" à elle.