2010-09-15 16 views
22

Czy to możliwe, aby powrócić do standardowego pojemnika z funkcji bez dokonywania kopię?Zwracanie C++ std :: wektor bez kopii?

Przykład Kod:

std::vector<A> MyFunc(); 

... 

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

W miarę jak zrozumieć to kopiuje wartość powrotu do nowego wektora B. Czy sprawienie, by funkcja zwróciła referencje lub coś w tym rodzaju pozwoliło uniknąć kopiowania?

+0

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

Odpowiedz

25

Jeśli kompilator wspiera NRVO to nie kopia zostanie wykonana, o ile spełnione są pewne warunki w funkcji powracającego obiekt. Na szczęście to zostało ostatecznie dodane w Visual C++ 2005 (v8.0) Może to mieć duży wpływ na perf, jeśli pojemnik jest duży, oczywiście.

Jeśli twój własny kompilator nie powie, czy jest on obsługiwany, powinieneś być w stanie skompilować kod C++ do asemblera (w trybie zoptymalizowanym/zwolnionym) i sprawdzić, co zostało zrobione za pomocą prostej przykładowej funkcji.

Jest również doskonałym szersza dyskusja here

+0

Dzięki! Masz jakieś pojęcie o NRVO w gcc? –

+0

@static_rtti - będę musiał odroczyć do ludzi Linux dla tego jednego, z obawy o oddanie nogę w ustach –

+0

można łatwo przetestować z klasy, która śledzi w kopii konstruktor. Zauważ, że jest to optymalizacja "może być", która niekoniecznie musi działać, np. z różnie nazwanymi obiektami powrotu. Jednak w przypadku wartości rvalue w C++ 0x klasy mogą implementować gwarancję. Można się tego spodziewać w przypadku standardowych pojemników w aktualnym STL. – peterchen

2

Jeśli można zmodyfikować podpis funkcji można użyć

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

lub

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

Można też wrócić inteligentnego wskaźnika , ale to wiąże się z nowymi obiektami.

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

HTH

+4

Pierwszy prawdopodobnie nie zadziała, jeśli zwrócisz wektor, który jest lokalny w funkcji. Drugi jest w porządku, ale – jcoder

+3

@John Burton/@ beezler - "nie będzie działać" łagodnie ujmuje to, zakładając, że zwrócony kontener jest oparty na stosie w wywołanej funkcji. –

13

Rvalues ​​(„uzupełnienia tymczasowe”) wiązał się const odniesienia będzie miał ich żywotność przedłużona do końca życia za odniesienie. Więc jeśli nie trzeba modyfikować ten wektor dodaje zrobi:

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

jeśli trzeba zmodyfikować wektor, tylko zakodować go w sposób, który jest najłatwiejszy do odczytania, aż dowód (otrzymany przez profilowanie), że ta linia ma nawet znaczenie pod względem wydajności.

przeciwnym razie polegać na C++ 1x z jego rvalue odniesień i przenieść semantykę idzie „prawdziwy wkrótce teraz” i optymalizacji, które kopiują bez konieczności zrobić wszystko.