2012-08-09 6 views
6

I push_back un oggetto temporaneo in un vector come questo,vector.push_back rvalue e copia-elisione

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

si applica il compilatore copia-elisione per costruire la temporanea A("abc") direttamente nel vector, cosicché A ' Il copyctor non verrà attivato quando si spinge l'oggetto temporaneo in vec.

+0

Non penso perché 'vector' (in realtà gli allocatori STL) utilizzano il posizionamento' new'. –

+0

@Seth Carnegie - in che modo si riferisce al posizionamento 'new'? Diciamo che hai abbastanza spazio libero nel vettore, quindi un compilatore può semplicemente costruire un'istanza di 'A' sul posto. –

+0

@Nya perché probabilmente il compilatore non capirà dove verrà creato (non che non possa farlo, ma non lo farà, perché gli scrittori di compilatori non hanno scritto quell'ottimizzazione). –

risposta

5

Se si dispone di un compilatore che supporta i riferimenti rvalue, verrà spostato nel vettore, che a volte è abbastanza economico.

Un'alternativa è quella di costruire direttamente l'oggetto nel vettore, che può essere fatto con vec.emplace_back("abc");. Questo richiama solo un costruttore.

Entrambe sono caratteristiche di C++ 11. Copia elision non è consentita qui, quindi senza queste funzionalità la copia verrà comunque eseguita.

Tuttavia, se il costruttore di copia non ha effetti collaterali osservabili (che non dovrebbe avere comunque), un compilatore intelligente può comunque eseguire tale ottimizzazione, perché la regola "as-if" consente qualsiasi ottimizzazione che risulti nel stesso comportamento osservabile. Non so se un compilatore corrente lo faccia, comunque. In caso contrario, dubito che qualcuno spenderà gli sforzi per aggiungere una tale ottimizzazione, perché i riferimenti di valore superiore pongono fine a tale esigenza.

+0

Attualmente non sto usando C++ 11. – Alcott

+0

@Alcott quindi è probabile che venga eseguita una copia. –

+0

@ R.MartinhoFernandes o l'operatore di assegnazione verrà chiamato; Ho visto che si verificano entrambi i casi, e credo che dipenda dal fatto che sia definito un costruttore di copie o che sia definito un operatore di assegnazione per la classe (forse entrambi?). Un'altra ragione per cui "Effective STL" è una lettura obbligata per tutti gli sviluppatori C++; Meyers parla dell'utilizzo delle classi con i contenitori STL e tocca il motivo/il modo di implementare le classi che verranno memorizzate al loro interno. – Will

1

Nel caso generale, non può essere fatto, potrebbe essere fatto qui come vector è un modello e il codice potrebbe essere inlineato, dando più informazioni all'ottimizzatore per fare il suo lavoro e alleggerendo alcuni dei requisiti della funzione chiamate.

Nel caso generale, copia elision funziona posizionando i due oggetti sulla stessa posizione in memoria e con solo due nomi per fare riferimento a un singolo oggetto. In questo caso, il problema sarebbe che uno degli argomenti deve trovarsi all'interno del vettore (allocati dinamicamente, in una posizione particolare) e l'altro è un argomento della funzione, che potrebbe essere vincolato dalla convenzione di chiamata a una posizione particolare nello stack. Se questo è il caso, il compilatore non sarà in grado di ottimizzare la copia.