K
Ethon schrieb:
Angenommen std::string hat einen Move-Ctor:
struct fooyou
{
int bar1;
std::string bar2;
fooyou() : bar1(0), bar2()
{ }
fooyou(int bar) : bar1(bar), bar2("bar entered")
{ }
};
fooyou test = fooyou(123);
Wird hier der String kopiert oder verschoben?
Wo genau ist "hier"? Ich nehme an, Du meinst damit die letzte Zeile mit der Kopierinitialisierung. Nun, weil auf der rechten Seite ein Rvalue-Ausdruck steht, darf der Compiler versuchen, die "Kopie" komplett wegzuoptimieren. Das heißt, ein gescheiter Compiler wird mit oder ohne Rvalue-Referenzen nur ein einziges Objekt vom Typ fooyou erzeugen, ohne dass irgendwas kopiert werden muss. Erwähnenswerte Änderungen in C++0x sind:
Überall dort, wo der C++03 Standard dem Compiler das Wegoptimieren von Kopien explizit erlaubt ("copy elision", siehe 12.8/15 [class.copy]) es aber aber aus irgendwelchen Gründen nicht tun kann, zwingt der kommende C++ Standard den Compiler, einen Move-Konstruktor zu benutzen (falls vorhanden).
Falls der Benutzer keinen Dtor, Copy-Ctor oder Copy-Assignment einer Klasse deklariert und falls die Datenelemente einer Klasse "move-bar" sind, erzeugt der Compiler entsprechende Move-Operationen automatisch.
In diesem konkreten Fall ist fooyou aufgrund der vom Compiler erzeugbaren Move-Operationen move-konstruierbar und move-zuweisbar. Also, entweder wird der Compiler direkt nur ein fooyou-Objekt erzeugen (falls er die "copy elision" durchführen kann) oder er wird seinen implizit generierten Move-Ctor für fooyou bemühen, welcher alle Datenelemente "movt". Es wird hier also garantiert kein String-Objekt kopiert.