web-dev-qa-db-fra.com

Passer std :: string par valeur ou référence

Duplicate possible:
Les jours de passage de const std :: string & en tant que paramètre sont-ils définis?

Dois-je passer std::string par valeur ou par référence (à une fonction non en ligne) si la sémantique de déplacement est prise en charge? Et qu'en est-il des implémentations utilisant l'optimisation de petite chaîne (SSO)?

72
Nordlöw

Il existe plusieurs réponses en fonction de ce que vous faites avec la chaîne.

1) Utiliser la chaîne comme identifiant (ne sera pas modifié). La passer par référence const est probablement la meilleure idée ici: (std::string const&)

2) Modifier la chaîne mais ne pas vouloir que l'appelant voie ce changement. La valeur par valeur est préférable: (std::string)

3) Modifier la chaîne mais vouloir que l'appelant voie ce changement. La passer par référence est préférable: (std::string &)

4) L'envoi de la chaîne dans la fonction et l'appelant de la fonction ne l'utilisera plus jamais. Utiliser déplacer la sémantique pourrait être une option (std::string &&)

127
linuxuser27

Vérifiez cette réponse pour C++ 11 . Fondamentalement, si vous passez une valeur lvalue à la référence rvalue

De cet article :

void f1(String s) {
    vector<String> v;
    v.Push_back(std::move(s));
}
void f2(const String &s) {
    vector<String> v;
    v.Push_back(s);
}

"Pour l'argument lvalue, 'f1' a une copie supplémentaire pour passer l'argument car il s'agit d'une valeur, alors que 'f2' a une copie supplémentaire pour appeler Push_back. Donc, aucune différence; pour l'argument rvalue, le compilateur doit créer un "Chaîne (L" ")" et transmettez quand même le temporaire à "f1" ou "f2". Parce que "f2" peut tirer parti de move ctor lorsque l'argument est temporaire (ce qui est une valeur), les coûts pour les arguments sont les mêmes maintenant pour "f1" et "f2". "

En continuant: "Cela signifie qu'en C++ 11, nous pouvons obtenir de meilleures performances en utilisant l'approche passage par valeur lorsque:

  1. Le type de paramètre prend en charge la sémantique de déplacement - Tous les composants de bibliothèque standard le font en C++ 11
  2. Le coût du constructeur de déménagement est beaucoup moins cher que celui de la copie (utilisation du temps et de la pile).
  3. Dans la fonction, le type de paramètre sera transmis à une autre fonction ou opération prenant en charge la copie et le déplacement.
  4. Il est courant de passer un temporaire comme argument - Vous pouvez organiser votre code pour le faire davantage.

"

OTOH, pour C++ 98, il est préférable de passer par référence - moins de données sont copiées. Passer const ou non const dépend de la nécessité de changer l'argument ou non.

19
emsr

Je crois que la réponse normale est qu’il devrait être passé par valeur si vous devez en faire une copie dans votre fonction. Passez-le par référence const sinon.

Voici une bonne discussion: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

4
Vaughn Cato