2012-08-09 15 views
6

I push_back ein temporäres Objekt in eine vector wie diese,vector.push_back rvalue und copy-elision

vector<A> vec; 
vec.push_back(A("abc")); 

wird der Compiler gelten copy-elision die temporäre A("abc") direkt in die vector zu konstruieren, so dass A ' s copy ctor wird nicht ausgelöst, wenn das temporäre Objekt in vec geschoben wird.

+0

Ich glaube nicht, weil 'Vektor' (STL-Zuweiser tatsächlich) Platzierung' neu' verwendet. –

+0

@Seth Carnegie - wie verhält es sich mit der Platzierung "neu"? Angenommen, Sie haben genug freien Speicherplatz in Vektor, dann kann ein Compiler nur eine Instanz von 'A' direkt anordnen. –

+0

@Nya, weil der Compiler wahrscheinlich nicht herausfinden wird, wo es erstellt wird (nicht dass es nicht kann, aber das wird nicht, weil Compiler-Schreiber diese Optimierung nicht geschrieben haben). –

Antwort

5

Wenn Sie einen Compiler haben, der Rvalue-Referenzen unterstützt, wird er in den Vektor verschoben, der manchmal ziemlich billig ist.

Eine Alternative dazu ist, das Objekt direkt im Vektor zu konstruieren, was mit vec.emplace_back("abc"); gemacht werden kann. Dies ruft nur einen Konstruktor auf.

Beide sind C++ 11 Funktionen. Kopieren ist hier nicht erlaubt, also wird ohne diese Funktionen die Kopie erstellt. Wenn der Kopierkonstruktor jedoch keine beobachtbaren Nebenwirkungen hat (was er ohnehin nicht haben sollte), kann ein intelligenter Compiler diese Optimierung dennoch ausführen, weil die "als-ob" -Regel jede Optimierung zulässt, die zu der. Führt dasselbe beobachtbare Verhalten. Ich weiß nicht, ob das ein aktueller Compiler tut. Wenn nicht, bezweifle ich, dass irgendjemand die Anstrengung aufwenden wird, eine solche Optimierung hinzuzufügen, weil R-Werte diesen Bedarf beenden.

+0

Ich benutze C++ 11 gerade nicht. – Alcott

+0

@Alcott dann wird wahrscheinlich eine Kopie erstellt. –

+0

@ R.MartinhoFernandes oder der Zuweisungsoperator wird aufgerufen; Ich habe beide Fälle auftreten sehen, und ich glaube, es hängt davon ab, ob ein Kopierkonstruktor definiert ist oder ob ein Zuweisungsoperator für die Klasse definiert ist (vielleicht beides?). Ein weiterer Grund, warum "Effective STL" für alle C++ - Entwickler ein Muss ist. Meyers spricht über die Verwendung von Klassen mit den STL-Containern und erläutert, warum/wie Klassen implementiert werden, die in ihnen gespeichert werden. – Will

1

Im allgemeinen Fall ist es nicht getan werden kann, ist es möglicherweise hier getan werden könnte, als vector eine Vorlage und der Code könnte inlined werden, weitere Informationen zu den Optimierer gibt es Arbeit zu tun und einige der Anforderungen der Funktion entlastet Anrufe.

Im allgemeinen Fall funktioniert copy elision, indem die zwei Objekte über dem gleichen Ort im Speicher platziert werden und nur zwei Namen haben, um auf ein einzelnes Objekt zu verweisen. Das Problem wäre in diesem Fall, dass eines der Argumente innerhalb des Vektors liegen muss (dynamisch zugewiesen an einer bestimmten Position) und das andere ein Argument für die Funktion ist, das durch die Aufrufkonvention an eine bestimmte Position gebunden sein kann im Stapel. Wenn dies der Fall ist, kann der Compiler die Kopie nicht optimieren.