Ma compréhension est qu'en C ++ 11, lorsque vous renvoyez une variable locale d'une fonction par valeur, le compilateur est autorisé à traiter cette variable comme une référence de valeur r et à la `` déplacer '' hors de la fonction pour la renvoyer (si RVO / NRVO ne se produit pas à la place, bien sûr).
Ma question est, cela ne peut-il pas casser le code existant?
Considérez le code suivant:
#include <iostream>
#include <string>
struct bar
{
bar(const std::string& str) : _str(str) {}
bar(const bar&) = delete;
bar(bar&& other) : _str(std::move(other._str)) {other._str = "Stolen";}
void print() {std::cout << _str << std::endl;}
std::string _str;
};
struct foo
{
foo(bar& b) : _b(b) {}
~foo() {_b.print();}
bar& _b;
};
bar foobar()
{
bar b("Hello, World!");
foo f(b);
return std::move(b);
}
int main()
{
foobar();
return EXIT_SUCCESS;
}
Mes pensées étaient qu'il serait possible pour un destructeur d'un objet local de référencer l'objet qui se déplace implicitement, et donc de voir de manière inattendue un objet «vide». J'ai essayé de tester cela (voir http://ideone.com/ZURoeT ), mais j'ai obtenu le résultat «correct» sans l'explicite std::move
dans foobar()
. Je suppose que c'était dû à NRVO, mais je n'ai pas essayé de réorganiser le code pour le désactiver.
Ai-je raison de dire que cette transformation (provoquant un déplacement hors de la fonction) se produit implicitement et pourrait casser le code existant?
MISE À JOUR Voici un exemple qui illustre ce dont je parle. Les deux liens suivants sont pour le même code. http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
Si vous regardez la sortie, c'est différent.
Donc, je suppose que cette question devient maintenant, a-t-elle été prise en compte lors de l'ajout d'un déplacement implicite à la norme, et il a été décidé qu'il était OK d'ajouter ce changement de rupture car ce type de code est assez rare? Je me demande également si des compilateurs avertiront dans des cas comme celui-ci ...