1
votes

Cet ajout de chaîne est-il une expression valide?

J'étais curieux de savoir si les opérateurs d'affectation composés sont valides pour plusieurs paramètres. Je suppose que + = n'aura aucun effet secondaire mais peut ne pas être le même cas avec "- =".

std::string a; 
a += "Hello" + " "+"World"; // doesn't compile
std::string name = "Old";
a += "Hello" + name +"World"; // compiles


4 commentaires

Pourquoi n'avez-vous pas simplement essayé de le compiler pour déterminer s'il est valide?


@JesperJuhl Pour être juste, ce n'est pas parce que le code compile qu'il est valide.


@ FrançoisAndrieux Bien sûr que non (comme je sais que vous savez que je sais). Mais il aurait laissé OP ajouter les informations supplémentaires: "il compile" ou "il ne compile pas avec cette erreur: ...". Et faire des tests de base vous-même (comme "est-ce que cela compile même?") Est une bonne habitude à prendre.


Ils (pas moi) pensaient probablement que vous n'aviez pas fait suffisamment de recherches avant de poser la question. C'est un peu subjectif.


3 Réponses :


4
votes

Ce n'est pas une expression valide car il n'y a pas d'opérateur + pour les littéraux de chaîne

#include <string>
#include <iostream>

int main()
{
    std::string a;
    std::string name = "Old";

    a += operator +( operator +( "Hello ", name ), " World" ); 

    std::cout << a << '\n';
}

(plus précisément pour les pointeurs car dans les expressions, les littéraux de chaîne avec de rares exceptions sont convertis en pointeurs vers leurs premiers symboles .)

Au lieu de cela, vous pourriez écrire

a += operator +( operator +( "Hello", name ), "World" ); 

Mais ce serait plus lisible si vous écrivez

template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
operator+(basic_string<charT, traits, Allocator>&& lhs, const charT* rhs);

Ou comme @Bathsheba l'a souligné dans un (précieux) commentaire à ma réponse, vous pouvez utiliser une chaîne littérale définie par l'utilisateur de la manière suivante

template<class charT, class traits, class Allocator>
basic_string<charT, traits, Allocator>
operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);

Quant à cette instruction

a += "Hello" + name +"World";

alors elle peut être réécrite en utilisant les opérateurs définis pour la classe std::basic_string

#include <string>
#include <iostream>

int main()
{
    using namespace std::string_literals;
    std::string a; 
    a += "Hello"s + " " + "World";

    std::cout << a << '\n';
}

et

a += "Hello";
a += " ";
a += "World";

comme

std::string a; 
( ( a += "Hello" ) += " " ) += "World";

Par exemple

"Hello" + " "+"World

Tenez compte du fait que chaque opérateur renvoie un objet de type std :: basic_string pour lequel l ' operator + est défini. C'est-à-dire qu'à chaque appel des opérateurs, un objet de type std :: basic_string est présent comme argument.


7 commentaires

Bienvenue à nouveau Vlad!


@Bathsheba Merci. Je suis heureux de vous rencontrer.:)


Ou vous pouvez simplement écrire a + = "Hello" "" "World" ou même `` a + = "Hello World" `, si vous vous sentez aventureux.


@DanM. Vous avez raison mais la question concerne l'opérateur +.


@bruno: Il a des profondeurs cachées. Notez que si a + = b était vraiment remplacé par a = a + b , alors le code se compilerait.


@DanM .: Que diriez-vous de a + = "Hello" s + "" + "World" ?


@bruno ou simplement pas de code du tout puisque vous n'utilisez jamais a : P



2
votes

L'expression a + = "Hello" + "" + "World" est groupée comme a + = ("Hello" + "" + " Monde ") .

Le côté droit est un ensemble de 3 littéraux const char [] . Ceux-ci se désintègrent en pointeurs const char * lorsqu'ils sont appliqués à l'addition binaire. Comme vous ne pouvez pas ajouter de pointeurs, le compilateur est requis pour émettre un diagnostic.

(Notez que l'expression apparemment équivalente a = a + "Hello" + "" + "World" est compilable.)


0 commentaires

4
votes

L'opérateur d'affectation composé + = n'y entre pas.

Vous pouvez utiliser + = avec std :: string parce que il définit la surcharge pertinente , mais seulement obtient un argument.

Et vous avez essayé de passer, comme cet argument, une expression construite par + ing plusieurs chaînes littérales. Cela ne se compilera pas.

Quelques alternatives, dans ce cas de jouet, qui peuvent inspirer une solution quel que soit votre cas réel:

Option 1

// Don't bother
std::string a;
a += "Hello World";


2 commentaires

Pourquoi le deuxième exemple compile-t-il?


@ ash007 C'est une fonctionnalité de langage , bien que peu connue.