Vous devez retourner par valeur.
La norme a une particularité pour améliorer l'efficacité du retour en valeur. C'est ce qu'on appelle "élision de copie", et plus précisément dans ce cas "l'optimisation de la valeur de retour nommée (NRVO)".
Compilateurs ne pas mettre en œuvre, mais là encore compilateurs n'ont à mettre en œuvre la fonction inline (ou effectuer une optimisation du tout). Mais les performances des bibliothèques standard peuvent être assez médiocres si les compilateurs n'optimisent pas, et tous les compilateurs sérieux implémentent l'inlining et NRVO (et d'autres optimisations).
Lorsque 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 faire ceci:
std::vector<int> myvec;
... some time later ...
myvec = f();
Copy elision n'empêche pas ici une copie car c'est une affectation plutôt qu'une initialisation. Cependant, vous devez toujours renvoyer par valeur. En C ++ 11, l'affectation est optimisée par quelque chose de différent, appelé "déplacer la sémantique". En C ++ 03, le code ci-dessus provoque une copie, et bien qu'en théorie un optimiseur puisse l'éviter, en pratique c'est trop difficile. Donc 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 flexible à l'utilisateur:
template <typename OutputIterator> void f(OutputIterator it) {
... write elements to the iterator like this ...
*it++ = 0;
*it++ = 1;
}
En plus de cela, vous pouvez également prendre en charge l'interface vectorielle existante:
std::vector<int> f() {
std::vector<int> result;
f(std::back_inserter(result));
return result;
}
Cela peut être moins efficace que votre code existant, si votre code existant utilise reserve()
d'une manière plus complexe qu'un montant fixe à l'avance. Mais si votre code existant appelle essentiellement push_back
le vecteur à plusieurs reprises, alors ce code basé sur un modèle devrait être aussi bon.
f
?