2010-09-15 4 views
22

Est-il possible de retourner un conteneur standard d'une fonction sans faire de copie?Retour d'un C++ std :: vector sans une copie?

code Exemple:

std::vector<A> MyFunc(); 

... 

std::vector<A> b = MyFunc(); 

Pour autant que je comprends, cette copie la valeur de retour dans un nouveau vecteur b. Est-ce que rendre la fonction retourne des références ou quelque chose comme ça permet d'éviter la copie?

+0

Duplicata de http://stackoverflow.com/questions/3703302/c-vector-return-vs-parameter/3703325#3703325? –

Répondre

25

Si votre compilateur prend en charge le NRVO, aucune copie ne sera effectuée, à condition que certaines conditions soient remplies dans la fonction renvoyant l'objet. Heureusement, cela a finalement été ajouté dans Visual C++ 2005 (v8.0) Cela peut avoir un impact majeur sur perf si le conteneur est grand, évidemment. Si vos propres compilateurs ne disent pas s'ils sont supportés, vous devriez pouvoir compiler le code C++ en assembleur (en mode optimisé/relâché) et vérifier ce qui est fait en utilisant une simple fonction d'exemple.

Il y a aussi une excellente discussion plus large here

+0

Merci! Une idée de NRVO dans gcc? –

+0

@static_rtti - Je devrais m'en remettre à des gens de Linux pour ça, de peur de mettre le pied dans la bouche –

+0

Vous pouvez facilement tester avec une classe qui trace dans la copie CTor. Notez que ceci est une optimisation "peut être", cela ne fonctionnera pas nécessairement par ex. avec des objets de retour nommés différemment. Cependant, avec les références C++ 0x rvalue, les classes peuvent implémenter une garantie. Vous pouvez vous attendre à cela pour des conteneurs standard dans un STL à jour. – peterchen

2

Si vous pouvez modifier la signature de la fonction, vous pouvez utiliser

std::vector<A>& MyFunc(); 

ou

void MyFunc(std::vector<A>& vect); 

Vous pouvez également retourner un pointeur intelligent , mais cela implique de nouveau l'objet.

some_smart_pointer<std::vector<A>> MyFunc(); 

HTH

+4

Le premier ne fonctionnera probablement pas si vous renvoyez un vecteur local dans la fonction. Le deuxième est bien si – jcoder

+3

@John Burton/@ beezler - 'ne va pas au travail', c'est un peu le cas, en supposant que le conteneur retourné est basé sur une pile dans la fonction appelée. –

13

rvalues ​​(« ») liés temporaires à const références auront leur durée de vie prolongée jusqu'à la fin de la durée de vie de la référence. Donc, si vous n'avez pas besoin de modifier ce vecteur, ce qui suit fera:

const std::vector<A>& b = MyFunc(); 

si vous devez modifier le vecteur, coder juste la manière qui est plus facile à lire jusqu'à ce que votre avoir la preuve (obtenue par profilage) que cette ligne importe même au niveau de la performance.

Sinon, comptez sur C++ 1x avec ses références rvalue et déplacez la sémantique à venir "très bientôt" et optimisez cette copie sans avoir à faire quoi que ce soit.

Questions connexes