J'ai donc lu des articles sur std::move
, std::forward
, rvalues, lvalues et ainsi de suite dans SO et d'autres endroits. Mais je trouve que je n'arrive pas à le saisir. Même si j'ai parfois des problèmes, je pense que je comprends les trucs de base sur les pointeurs, les références, etc. qui étaient en C++ avant tout ça. Est-ce que c'est moi ou est-ce que ces trucs deviennent trop lourds ?
Réponses
Trop de publicités?Je vous recommande de lire la proposition originale si vous ne l'avez pas déjà fait :
Une proposition pour ajouter le support de la sémantique des mouvements au langage C++
Il expose très clairement les problèmes qui peuvent être résolus avec les références rvalue et la sémantique de déplacement et comment les références rvalue et la sémantique de déplacement peuvent être utilisées pour résoudre ces problèmes.
Les documents des comités de normalisation sont souvent denses et difficiles à comprendre, mais celui-ci est très accessible et vaut vraiment la peine d'être lu. Les références rvalue et la sémantique des déplacements telles qu'elles seront spécifiées dans la norme finale C++0x (quand cela arrivera) peuvent être différentes de ce qui est proposé dans ce document, mais les concepts restent les mêmes.
Votre question est très générale. Je peux peut-être vous aider à démarrer :
- Ignorer les fonctions
std:move()
etstd::forward()
au début - Un aspect de Références RValue est de sauver les temporaires.
- En code C++03, comptez les temps pour
Matrix z = a + b + c + d;
(avecMatrix a,b,c,d;
) - mettez vous en œuvre
operator+
surMatrix
avec une surcharge Références RValue . - vous devriez être en mesure de réduire considérablement le nombre de temporaires.
- En code C++03, comptez les temps pour
Si vous voulez voir une utilisation simple de std::move()
: Aide le compilateur à éviter d'introduire une copie pour une valeur de retour :
-
Créez une classe de conteneur comme
Image
-- coûteux à copier. -
N'oubliez pas de mettre en œuvre le déplacer et copier-coller
-
inventer une fonction d'usine qui fonctionne comme ceci :
Image load\_matching\_size(const char \*fn\_small, const char \*fn\_big) { pair<Image> ii = load\_2\_images(fn\_small, fn\_big); **return ii.first.width() >= 64 ? ii.first : ii.second**; }
-
Pouvez-vous compter le nombre de temporaires ? Notez que le
return
aura besoin d'un autre et d'une copie ! (L'exemple est conçu pour que optimisation de la valeur de retour ("RVO") ne devrait pas être possible) -
Pouvez-vous voir que cela ne serait pas nécessaire ? Les images dans
ii
sera jeté peu de temps après le retour de la fonction. Le compilateur pourrait-il utiliser alors pour la valeur de retour ? (Non, il ne pourrait pas. RVO fonctionnerait si nous n'avions qu'une seuleImage
). -
Avec
move
en elreturn
vous pouvez dire au compilateur, que vous n'avez pas besoin deii
plus loin et qu'il peut l'utiliser pour le retour. Et ainsi s'épargner une copie coûteuse de mon utilisation des move-c'tor au lieu de la copie-c'tor pour le retour.