J'ai une question très basique: est-ce une bonne idée de retourner un std::vector<A>
en utilisant std::move
? Par exemple:
class A {};
std::vector<A> && func() {
std::vector<A> v;
/* fill v */
return std::move(v);
}
Dois-je revenir std::map
, std::list
.. etc ... de cette façon?
Vous déclarez une fonction à renvoyer par référence de valeur r - cela ne devrait presque jamais être fait (si vous retournez l'objet local par référence, vous vous retrouverez avec une référence pendante). Au lieu de cela, déclarez la fonction à renvoyer par valeur. De cette façon, la valeur de l'appelant sera déplacée par la valeur r renvoyée par la fonction. La valeur retournée sera également liée à toute référence.
Deuxièmement, non, vous ne devez pas retourner en utilisant un std::move
car cela empêchera le compilateur d'utiliser RVO . Il n'y a pas besoin car le compilateur convertira automatiquement toute référence de valeur l retournée en référence de valeur r si possible.
std::vector<A> func() {
std::vector<A> v;
/* fill v */
return v; // 'v' is converted to r-value and return value is move constructed.
}
Non, ça ne l'est pas. Cela empêchera en fait la suppression de la copie dans certains cas. Il y a même un avertissement dans certains compilateurs à ce sujet, appelé -Wpessimizing-move
.
Comme les réponses avant moi, il suffit de le renvoyer par valeur, en changeant simplement le type de retour std::vector<A>
, et le compilateur se chargera d'appeler le constructeur de déplacement si nécessaire.
Vous pouvez jeter un oeil à ce post que je viens de trouver, qui semble l'expliquer en détail (bien que je ne l'ai pas lu moi-même): https://vmpstr.blogspot.hu/2015/12/ redundant-stdmove.html
Les compilateurs gcc et clang avec optimisation activée génèrent le même code binaire dans les deux cas lorsque vous renvoyez une variable locale et lorsque vous écrivez std::move()
. Renvoyez simplement une valeur.
Mais en utilisant &&
et noexcept
spécificateur est utile si vous créez un constructeur en mouvement et en déplaçant operator=
pour votre classe personnalisée