Ja, der Compiler kann RVO ausführen. Ich habe einen Testcode ausgearbeitet und habe ihn durch godbolt geleitet:
%Vor% g++ -O3
erzeugt
Auffallend bei der Disassembly fehlt jeder Aufruf des Copy- oder Move-Konstruktors von M
.
Auch der Abschnitt des Standards, der die Kriterien für die Kopierfreigabe festlegt, unterscheidet nicht zwischen virtuellen und nichtvirtuellen Elementfunktionen, und wenn der Standard für die Eliminierung der Kopie erfüllt ist, wird die Überladungsauflösung für die return
-Anweisung zuerst ausgeführt wenn das Objekt mit einem rvalue gekennzeichnet wurde ".
Das heißt, in einer Funktion
%Vor% Wenn die Kopieroperation aus irgendeinem Grund nicht ausgeführt werden kann und ein Move-Konstruktor verfügbar ist, ruft return m;
immer den Move-Konstruktor und nicht den Kopierkonstruktor auf. Daher müssen Sie std::move
für die return-Anweisung nicht verwenden, wenn Sie eine lokale Variable zurückgeben.
Wenn du return std::move(result);
hast, kannst du nichts gewinnen und du kannst verlieren. Also tu es nicht.
Sie können nichts gewinnen, weil der Standard explizit besagt, "wenn RVO-Bedingungen erfüllt sind, oder Sie einen Parameter zurückgeben, versuchen Sie zuerst als rvalue zurückzugeben und nur, wenn das nicht kompilieren würde, zurück als lvalue. Selbst wenn Sie return result;
haben, ist der Compiler gezwungen , um return std::move(result);
first zu versuchen.
Sie können verlieren, da return std::move(result);
spezifisch RVO verhindert, wenn es anderweitig anwendbar wäre.