Vous devez retourner par valeur.
La norme a une caractéristique spécifique pour améliorer l'efficacité du retour par valeur. Elle s'appelle "copy elision", et plus spécifiquement dans ce cas la "named return value optimization (NRVO)".
Les compilateurs n'ont pas à l'implémenter, mais là encore, les compilateurs n'ont pas à le faire. ont pour implémenter l'inlining des fonctions (ou pour effectuer une quelconque optimisation). Mais les performances des bibliothèques standard peuvent être assez faibles si les compilateurs n'optimisent pas, et tous les compilateurs sérieux implémentent l'inlining et le NRVO (et d'autres optimisations).
Lorsque le NRVO est appliqué, il n'y aura pas de copie dans le code suivant :
std::vector<int> f() {
std::vector<int> result;
... populate the vector ...
return result;
}
std::vector<int> myvec = f();
Mais l'utilisateur peut vouloir le faire :
std::vector<int> myvec;
... some time later ...
myvec = f();
L'élision de copie n'empêche pas une copie ici car il s'agit d'une affectation plutôt que d'une initialisation. Cependant, vous devriez toujours retourner par valeur. En C++11, l'affectation est optimisée par quelque chose de différent, appelé "move semantics". En C++03, le code ci-dessus provoque une copie, et bien que en théorie un optimiseur pourrait être capable de l'éviter, mais en pratique, c'est trop difficile. Ainsi, au lieu de myvec = f()
En C++03, vous devriez écrire ceci :
std::vector<int> myvec;
... some time later ...
f().swap(myvec);
Il existe une autre option, qui consiste à offrir une interface plus souple à l'utilisateur :
template <typename OutputIterator> void f(OutputIterator it) {
... write elements to the iterator like this ...
*it++ = 0;
*it++ = 1;
}
Vous pouvez alors également prendre en charge l'interface vectorielle existante :
std::vector<int> f() {
std::vector<int> result;
f(std::back_inserter(result));
return result;
}
Ce site pourrait être moins efficace que votre code existant, si votre code existant utilise reserve()
d'une manière plus complexe qu'un simple montant fixe à l'avance. Mais si votre code existant appelle essentiellement push_back
sur le vecteur de manière répétée, alors ce code basé sur un modèle devrait être aussi bon.