Le retour par référence rvalue est-il plus efficace?

par exemple:

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

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

Cela renvoie une référence en suspens, comme avec le cas de référence lvalue. Après le retour de la fonction, l’object temporaire sera détruit. Vous devez renvoyer Beta_ab par valeur, comme suit:

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

Maintenant, il est approprié de déplacer un object Beta_ab temporaire dans la valeur de retour de la fonction. Si le compilateur le peut, cela évitera le déplacement, en utilisant RVO (optimisation de la valeur de retour). Maintenant, vous pouvez faire ce qui suit

 Beta_ab ab = others.toAB(); 

Et il déplacera le temporaire dans ab , ou RVO omettra de faire un mouvement ou une copie. Je vous recommande de lire BoostCon09 Rvalue References 101, qui explique le problème et comment (N) RVO interagit avec cela.


Votre cas de retour d’une référence de valeur serait une bonne idée dans d’autres occasions. Imaginez que vous ayez une fonction getAB() que vous getAB() souvent sur un getAB() temporaire. Ce n’est pas optimal de le faire renvoyer une référence de const lvalue pour les provisoires rvalue. Vous pouvez l’implémenter comme ça

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

Notez que move dans ce cas n’est pas facultatif, car ab n’est ni une automatique locale ni une valeur temporaire. Maintenant, le qualificatif ref && dit que la deuxième fonction est invoquée sur les temporelles rvalue, faisant le déplacement suivant, au lieu de copier

 Beta_ab ab = Beta().getAB(); 

Il peut être plus efficace, par exemple, dans un contexte un peu différent:

 template  T&& min_(T&& a, T &&b) { return std::move(a < b? a: b); } int main() { const std::string s = min_(std::string("A"), std::string("B")); fprintf(stderr, "min: %s\n", s.c_str()); return 0; } 

Comme observation intéressante, sur ma machine, clang++ -O3 génère 54 instructions pour le code ci-dessus contre 62 instructions pour std::min standard. Cependant, avec -O0 il génère 518 instructions pour le code ci-dessus contre 481 pour std::min .