To move or not to move
-
vector<string> stuff; { string s = getStuff(); if (s.size()) stuff.push_back(move(s)); }Sollte ich hier das move weglassen, weil der Compiler s selbst als Temporary erkennt?
Es hieß mal irgendwo, dassreturn move(value);ineffizienter als
return value;bei lokalen Variablen ist.
-
In deinem Beispielcode steht kein return. Warum sollte dein "es hiess mal" also dort greifen. Desweiteren sollte std::move nur den Typ umwandeln, d.h. es ist eine nop und sorgt nur dafuer, dass die "richtige" ueberladung ausgewaehlt wird. Keine Ahnung, ob es unter http://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler faellt.
-
nwp3 schrieb:
Sollte ich hier das move weglassen, weil der Compiler s selbst als Temporary erkennt?
Selbst wenn der Compiler so schlau sein sollte, dass er das erkennt, darf er hier kein move automatisch verwenden -- zumindest nicht in einer "as-if"-Regel-verletzenden Weise. Deine Verwendung von std::move ist hier also genau richtig und vordbildlich.
Die einzige Stelle, bei der ein Compiler ein Lvalue als Rvalue behandeln darf, ist beim
returneines funktionslokalen Objekts.nwp3 schrieb:
Es hieß mal irgendwo, dass
return move(value);ineffizienter als
return value;bei lokalen Variablen ist.
Genau. Du hebelst nämlich durch diese Verwendung von
movedie NRVO-Optimierung aus, die ein Compiler hier sonst anwenden dürfte (und typischerweise auch tut). NRVO ist noch günstiger als eine Move-Konstruktion. Mit std::move würdest du hier mindestens eine Move-Konstruktion bekommen, weil die Copy-Elision-Regel nicht mehr greifen kann. Das liegt daran, dass std::move etwas mehr als ein Cast ist: Es ist ein Funktionsaufruf -- auch wenn dieser geinlined werden kann und die Funktion sonst nichts besonderes macht.
-
krümelkacker schrieb:
...
Vielen Dank!
-