2010-09-15 8 views
22

Kann ein Standardcontainer von einer Funktion zurückgegeben werden, ohne eine Kopie zu erstellen?Einen C++ std :: Vektor ohne Kopie zurückgeben?

Beispielcode:

std::vector<A> MyFunc(); 

... 

std::vector<A> b = MyFunc(); 

Soweit ich verstehe, diese Kopien der Rückgabewert in einen neuen Vektor b. Verleiht die Funktion die Rückgabe von Referenzen oder Ähnlichem, um die Kopie zu vermeiden?

+0

Doppelte von http://stackoverflow.com/questions/3703302/c-vector-return-vs-parameter/3703325#3703325? –

Antwort

25

Wenn Ihr Compiler das NRVO unterstützt, wird keine Kopie erstellt, sofern in der Funktion, die das Objekt zurückgibt, bestimmte Bedingungen erfüllt sind. Zum Glück wurde dies schließlich in Visual C++ 2005 (v8.0) hinzugefügt Dies kann eine große + ve Auswirkungen auf Perf haben, wenn der Container offensichtlich groß ist.

Wenn Ihre eigenen Compiler-Dokumente nicht sagen, ob es unterstützt wird, sollten Sie in der Lage sein, den C++ - Code zu assembler (im optimierten/release-Modus) zu kompilieren und zu überprüfen, was mit einer einfachen Beispielfunktion getan wird.

Es gibt auch eine ausgezeichnete breitere Diskussion here

+0

Danke! Irgendeine Idee über NRVO in gcc? –

+0

@static_rtti - Ich werde auf Linux-Leute für diesen einen aufschieben müssen, aus Angst davor, Fuß in den Mund zu setzen –

+0

Sie können leicht mit einer Klasse, die in der Kopie CTor verfolgt, testen. Beachten Sie, dass dies eine "can be" -Optimierung ist, die nicht unbedingt z. mit unterschiedlich benannten Rückgabeobjekten. Mit C++ 0x rvalue-Verweisen können Klassen jedoch eine Garantie implementieren. Sie können dies für Standardcontainer in einer aktuellen STL erwarten. – peterchen

2

Wenn Sie die Signatur der Funktion ändern können, dann können Sie

std::vector<A>& MyFunc(); 

oder

void MyFunc(std::vector<A>& vect); 

Sie könnten verwenden auch einen intelligenten Zeiger zurückgeben , aber das beinhaltet das neue Objekt.

some_smart_pointer<std::vector<A>> MyFunc(); 

HTH

+4

Die erste wird wahrscheinlich nicht funktionieren, wenn Sie einen Vektor zurückgeben, der in der Funktion lokal ist. Der zweite ist in Ordnung, obwohl – jcoder

+3

@John Burton/@ Beezler - "geht nicht zur Arbeit" ist es gelinde gesagt, unter der Annahme, dass der zurückgegebene Container Stack-basierte in der aufgerufenen Funktion ist. –

13

Rvalues ​​(„Provisorien“) gebunden zu const Referenzen werden ihre Lebensdauer bis zum Ende der Laufzeit des Bezugs verlängert haben. Also, wenn Sie diesen Vektor nicht ändern müssen, wird Folgendes tun:

const std::vector<A>& b = MyFunc(); 

wenn Sie den Vektor ändern müssen, es ist nur die Art und Weise codieren, die am einfachsten zu lesen, bis der Beweis haben (erhalten durch Profiling), dass diese Linie sogar leistungsbezogen ist.

Andernfalls verlassen Sie sich auf C++ 1x mit seinen Rvalue-Referenzen und verschieben Semantik kommt "real bald" und Optimierung dieser Kopie, ohne dass Sie etwas tun müssen.