Les codes suivants font échouer VC2010:
template<class _Ty> inline typename tr1::_Remove_reference<_Ty>::_Type&& move(_Ty&& _Arg) { // forward _Arg as movable return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg); }
5 Réponses :
Vous pouvez penser à dans votre exemple "code2", Nous pouvons également faire le contraire de Ceci est principalement utile pour one-liners pervers ou impressionner les filles à un bar. p> p> std :: Déplacer code> comme juste une distribution (mais une expression em> couler, pas un type de type de type). L'expression
std :: mouvement (x) code> est une rvalue avec la même valeur que
x code>, mais cela fonctionne même si
x code> est un lvalue .
x code> est en effet une lvalue (de type "RValue référence à la chaîne"). Ce lvalue ne peut pas se lier au type de retour de la fonction ("Revalue référence à la chaîne"), de sorte que vous devez la jeter explicitement à une expression de rvalue. P>
déplacer Code>, que j'appelle habituellement
restez code>, qui transforme les rvalues en lvalues (utilisation avec soin!): p>
L'astuce Voici que les références de rvalue fonctionnent de manière conforelle sur les paramètres de modèle: P> Si le paramètre de modèle Ceci est à cause du chemin donc lorsque vous appelez std :: Déplacer code> S est une référence de rvalue, qui semble confusion - pourquoi pouvez-vous appeler
déplacer (STR) code>, lorsque
STR code> n'est pas une rvalue?
t code> est
int < / code>, puis
t && code> sera une référence de rvalue
int && code>.
Mais si t code> est une référence de lvalue
int & code>, puis
t && code> sera également de référence de lvalue
int & code>. P>.
& code> et
&& code> combine: p>
déplacer (STR) code>,
t code> est
std :: string & code> et le type de paramètre de
déplacer
std :: string & code> - une référence de Lvalue, qui permet à l'appel de la fonction de compiler. Ensuite, tous les
déplacer code> doivent faire la valeur à une référence de rvalue. P> p>
+1 Ah, vous avez repéré la confusion de l'Op beaucoup mieux. Le type d'argument code> de code> n'est pas une référence de rvalue, mais une référence universelle i>.
Il y a quelques articles pour expliquer n ° 1, mais je ne comprends pas pourquoi # 2 Également échoue. P>
N'oubliez pas que s'il a un nom, c'est un
lvalue fort>. Dans votre deuxième cas, X est toujours un lvalue fort> même s'il s'agit d'une référence RValue forte>. Std :: Déplacer Code> a la capacité de transformer
lvalues forte> dans RValues forte> en ne faisant rien de plus qu'un static_cast
(Yourvar) sur eux. L'expression résultante est une r devale qui peut être acceptée par n'importe quel code demandant une référence RValue forte>. (un type && code>) p>
Je vais illustrer avec quelques exemples. Dans votre exemple d'origine, remplacez: p>
xxx pré> avec p>
xxx pré> là, l'objet String n'a plus de nom, il est maintenant une rvalue forte> et est acceptée par test1. P>
Comment fonctionne-t-elle? Encore une fois, assez simple. Encore une fois, remplacez votre appel par: p>
test1(static_cast<std::string&&>(str));
Les gens ici ont déjà répondu à la question, mais je pense que cela doit être dit plus explicitement. La raison pour laquelle les gens sont souvent confondus avec des références de rvalue sont dans la règle:
déroutant au début, cette règle a du sens. L'objectif d'une référence de rvalue est de se lier à l'objet que vous n'aurez plus besoin de: soit à une temporaire ni à quelque chose que vous savez que vous n'aurez jamais besoin, mais le compilateur ne serait pas en mesure de le comprendre. p> Une référence de rvalue nommée est quelque chose que vous pouvez faire référence à plusieurs fois: p> ici, j'ai créé une temporaire dans la première ligne mais À la reliure à la référence de la rvalue, je l'ai fait fonctionner presque comme un objet automatique: je peux y accéder plusieurs fois. Et pour que la dernière ligne fonctionne, la deuxième ligne ne doit pas compiler. P> Que std :: Déplacer code> est de modifier une référence de rvalue nommée (une lvalue) vers un Référence de rvalue sans nom (une rvalue). P> p>
La magie de la sémantique de déplacement consiste à exploiter la destruction. p>
Imaginez une classe qui gère la durée de vie d'un tampon alloué de manière dynamique comme STD :: String:
Un constructeur de copie prenant Si nous pouvons (en surchargeant le constructeur de copie pour Comme indiqué précédemment, une référence de rvalue est une lvalue (cela nous a permis d'accéder complet afin de voler le tampon dans l'exemple ci-dessus). Supposons maintenant que nous voulions utiliser l'argument dans
Un autre, expression d'appel surchargé de simulaire: sans String Const & code> ne peut pas savoir si l'argument est réellement nécessaire après et doit donc toujours cloner ce tampon, ce qui peut être une opération coûteuse. P>
String && code>) Sachez que l'argument est jetable, nous ne pouvons que "voler" le tampon de ne pas avoir à copier (sur et sur des expressions complexes). p>
std :: Déplacer code> L'argument nous semble précieux et que la surcharge
String Const & code> est résolue alors que
std :: Déplacer Code > nous permet
Pour répéter le "bouge de mouvement" (parce que nous savons que l'argument provenait d'une r devalue sur le site d'appel). P>
Dans le second cas,
x code> est une référence rvalue i>, ce n'est pas une rvalue elle-même (car elle a un nom).
Stackoverflow.com/questions/5529881/... < / a> Stackoverflow.com/ Questions / 7510182 / ...