Meines Wissens nach kann der Compiler in C ++ 11, wenn Sie eine lokale Variable von einer Funktion nach Wert zurückgeben, diese Variable als R-Wert-Referenz behandeln und sie aus der Funktion 'verschieben', um sie zurückzugeben (if RVO / NRVO passiert natürlich nicht stattdessen).
Meine Frage ist, kann dies nicht vorhandenen Code brechen?
Betrachten Sie den folgenden Code:
#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;
}
Meine Gedanken waren, dass es einem Destruktor eines lokalen Objekts möglich sein würde, auf das Objekt zu verweisen, das implizit verschoben wird, und daher unerwartet ein "leeres" Objekt zu sehen. Ich habe versucht, dies zu testen (siehe http://ideone.com/ZURoeT ), aber ich habe das 'richtige' Ergebnis ohne das explizite std::move
in erhalten foobar()
. Ich vermute, das lag an NRVO, aber ich habe nicht versucht, den Code neu zu ordnen, um das zu deaktivieren.
Stimmt es, dass diese Transformation (die zu einem Verschieben der Funktion führt) implizit erfolgt und vorhandenen Code beschädigen kann?
UPDATE Hier ist ein Beispiel, das zeigt, wovon ich spreche. Die folgenden zwei Links beziehen sich auf denselben Code. http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
Wenn Sie sich die Ausgabe ansehen, ist es anders.
Ich denke, diese Frage wird nun, wurde dies beim Hinzufügen einer impliziten Verschiebung zum Standard berücksichtigt, und es wurde entschieden, dass es in Ordnung war, diese bahnbrechende Änderung hinzuzufügen, da diese Art von Code selten genug ist. Ich frage mich auch, ob Compiler in solchen Fällen warnen werden ...