Réponses:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Cela renvoie une référence pendante, 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 renvoyer Beta_ab
par valeur, comme suit
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Maintenant, il déplace correctement un Beta_ab
objet temporaire dans la valeur de retour de la fonction. Si le compilateur le peut, il évitera complètement 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 la construction du temporaire dans ab
, ou fera RVO pour omettre de faire un déplacement 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 renvoi d'une référence rvalue serait une bonne idée dans d'autres occasions. Imaginez que vous ayez une getAB()
fonction que vous invoquez souvent de manière temporaire. Il n'est pas optimal de lui faire renvoyer une référence const lvalue pour les temporaires rvalue. Vous pouvez l'implémenter comme ceci
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Notez que move
dans ce cas, ce n'est pas facultatif, car il ab
ne s'agit ni d'une valeur automatique locale ni d'une rvalue temporaire. Maintenant, le qualificatif ref &&
dit que la deuxième fonction est invoquée sur les temporaires rvalue, faisant le mouvement suivant, au lieu de copier
Beta_ab ab = Beta().getAB();
Cela peut être plus efficace, par exemple, dans un contexte un peu différent:
template <typename T>
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 le standard std::min
. Cependant, -O0
il génère 518 instructions pour le code ci-dessus contre 481 pour le code normal std::min
.
for(:)
et une intégration sur un objet désalloué. Correction: ideone.com/tQVOal
std::move()
est simplement utilisé comme une distribution explicite pour illustrer plus clairement le point. Ce n'est pas un code que vous copieriez-coller dans votre projet. Cela ne contredit pas la réponse la plus votée, car un objet temporaire est créé à l'intérieur de la fonction. Ici, l'objet renvoyé est l'un des arguments (les objets temporaires sont détruits lors de la dernière étape de l'évaluation de l'expression complète qui (lexicalement) contient le point où ils ont été créés).