2010-09-15 11 views
22

E 'possibile restituire un contenitore standard da una funzione senza fare una copia?Restituisce un C++ std :: vector senza una copia?

codice Esempio:

std::vector<A> MyFunc(); 

... 

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

Per quanto ho capito, questa copia il valore di ritorno in un nuovo vettore b. Rendere i riferimenti alla funzione restituita o qualcosa del genere consente di evitare la copia?

+0

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

risposta

25

Se il compilatore supporta NRVO, non verrà eseguita alcuna copia, purché nella funzione di restituzione dell'oggetto siano soddisfatte determinate condizioni. Fortunatamente, questo è stato finalmente aggiunto in Visual C++ 2005 (v8.0) Questo può avere un maggiore impatto di + ve su perf se il contenitore è grande, ovviamente.

Se i doc del proprio compilatore non dicono se è supportato o meno, si dovrebbe essere in grado di compilare il codice C++ sull'assemblatore (in modalità ottimizzata/rilascio) e controllare cosa viene fatto usando una semplice funzione di esempio.

C'è anche un ottimo discorso più ampio here

+0

Grazie! Qualche idea su NRVO in gcc? –

+0

@static_rtti - Dovrò rimandare a gente Linux per quello, per paura di mettere il piede in bocca –

+0

Puoi facilmente testare con una classe che ricalca nella Copia CTor. Nota che questa è un'ottimizzazione "può essere", che non funzionerà necessariamente ad es. con oggetti di ritorno con nome diverso. Tuttavia, con riferimenti razionali di C++ 0x, le classi possono implementare una garanzia. Potete aspettarlo per contenitori standard in un STL aggiornato. – peterchen

2

Se è possibile modificare la firma della funzione, è possibile utilizzare

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

o

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

Si potrebbe anche restituire un puntatore intelligente , ma ciò comporta la creazione di nuovo l'oggetto.

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

HTH

+4

Il primo potrebbe non funzionare se si restituisce un vettore che è un locale nella funzione. Il secondo va bene anche se – jcoder

+3

@John Burton/@ beezler - 'non sta andando a lavorare' lo sta mettendo leggermente, supponendo che il contenitore restituito sia basato sullo stack nella funzione chiamata. –

13

rvalues ​​("provvisori") legate al const riferimenti avranno il loro ciclo di vita esteso fino alla fine del ciclo di vita del riferimento. Quindi, se non è necessario modificare tale vettore, il seguente farà:

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

se è necessario modificare il vettore, basta codificare il modo che è più facile da leggere fino a quando vostro avere la prova (ottenuta attraverso profilazione) che questa linea è importante anche per le prestazioni.

In caso contrario, fare affidamento su C++ 1x con i suoi riferimenti rvalue e spostare la semantica in arrivo "real soon soon" e ottimizzarne la copia senza dover fare nulla.