2009-07-12 8 views

Répondre

165
Beta_ab&& 
Beta::toAB() const { 
    return move(Beta_ab(1, 1)); 
} 

Ceci retourne une référence boiteuse, tout comme avec le cas de référence lvalue. Après le retour de la fonction, l'objet temporaire sera détruit. Vous devez retourner Beta_ab en valeur, comme ce qui suit

Beta_ab 
Beta::toAB() const { 
    return Beta_ab(1, 1); 
} 

Maintenant, il se déplace correctement un objet Beta_ab temporaire dans la valeur de retour de la fonction. Si le compilateur le peut, il évitera le mouvement en utilisant RVO (optimisation de la valeur de retour). Maintenant, vous pouvez effectuer les opérations suivantes

Beta_ab ab = others.toAB(); 

Et elle se transporterait construire le temporaire dans ab, ou faire RVO d'omettre de faire un déplacement ou de copie tout à fait. Je vous recommande de lire BoostCon09 Rvalue References 101 qui explique la question, et comment (R) RVO arrive à interagir avec cela.


Votre cas de renvoi d'une référence rvalue serait une bonne idée dans d'autres occasions. Imaginez que vous avez une fonction getAB() que vous appelez souvent sur un temporaire. Il n'est pas optimal de lui faire renvoyer une référence constlvalue pour les valeurs temporaires. Vous pouvez le mettre en œuvre comme cette

struct Beta { 
    Beta_ab ab; 
    Beta_ab const& getAB() const& { return ab; } 
    Beta_ab && getAB() && { return move(ab); } 
}; 

Notez que move dans ce cas est pas une option, car ab est ni automatique locale ni une rvalue temporaire. Maintenant, le ref-qualification&& dit que la deuxième fonction est appelée sur les temporaires rvalue, ce qui rend le mouvement suivant, au lieu de copier

Beta_ab ab = Beta().getAB(); 
+32

J'avais toujours pris le problème de référence boiteuse est parti automagiquement lorsque le type de retour est une référence de valeur-r. Je suis content que je l'ai bien compris avant de me mordre. Stack brisant les insectes sucent. –

+17

:) Vraiment, les références rvalue sont "juste des références" comme les références lvalue. ils ne copient ou ne stockent rien. –

+0

Et même s'il n'élimine pas les constructeurs, le compilateur sait qu'il peut renvoyer automatiquement un rvalue-ref pour vous en toute sécurité. Par exemple, d'après mes expériences, 'return x;' est la même chose que 'return std :: move (x)'. (où 'x' est une variable locale (c'est-à-dire que ce point que j'ai fait ne s'applique pas directement à la question initiale concernant le renvoi d'un caractère temporaire)). –

Questions connexes