92 votes

Passage de std::string par valeur ou référence

Duplicata possible :
L'époque où l'on passait const std::string & comme paramètre est-elle révolue ?

Devrais-je passer std::string par valeur ou par référence (à une fonction nonlined) si la sémantique move est supportée ? Et qu'en est-il des implémentations utilisant l'optimisation des petites chaînes de caractères (SSO) ?

162voto

linuxuser27 Points 4095

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

1) Utilisation de la chaîne de caractères comme identifiant (qui ne sera pas modifié). Le passage par une référence constante est probablement la meilleure idée ici : (std::string const&)

2) Modifier la chaîne de caractères mais ne pas vouloir que l'appelant voie cette modification. Il est préférable de la transmettre par valeur : (std::string)

3) Modifier la chaîne de caractères mais vouloir que l'appelant voie cette modification. Il est préférable de la faire passer par référence : (std::string &)

4) Envoyer la chaîne dans la fonction et l'appelant de la fonction n'utilisera plus jamais la chaîne. Utilisation de sémantique du déplacement pourrait être une option (std::string &&)

23voto

emsr Points 4616

Vérifiez cette réponse pour C++11 . Fondamentalement, si vous passez une 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 est by-value, tandis que 'f2' a une copie supplémentaire pour appeler push_back. Il n'y a donc pas de différence ; pour un argument rvalue, le compilateur doit créer un temporaire 'String(L"")' et passer le temporaire à 'f1' ou 'f2' de toute façon. Parce que 'f2' peut profiter de move ctor quand l'argument est un temporaire (qui est une rvalue), les coûts pour passer l'argument sont les mêmes maintenant pour 'f1' et 'f2'."

Continuant : " Cela signifie que dans C++11, nous pouvons obtenir de meilleures performances en utilisant l'approche pass-by-value lorsque :

  1. Le type de paramètre prend en charge la sémantique de déplacement - Tous les composants de la bibliothèque standard le font en C++11.
  2. Le coût du constructeur de déplacement est beaucoup moins élevé que celui du constructeur de copie. (tant au niveau du temps que de l'utilisation de la pile).
  3. À l'intérieur de la fonction, le type de paramètre sera transmis à une autre fonction ou opération. qui supporte à la fois 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.

"

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

4voto

Vaughn Cato Points 30511

Je pense que la réponse normale est qu'il doit être passé par valeur si vous avez besoin d'en faire une copie dans votre fonction. Sinon, passez-le par référence constante.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X