Ci sono due copie in C++ 03 e due mosse in C++ 11.
Sia in C++ 03 che in C++ 11 la copia/le mosse sono soggette a elision e, come tale (in un esempio come questo) è probabile che non si verifichi alcuna copia/spostamento.
vector<int> myVector() {
vector<int> res;
res.push_back(4);
res.push_back(5);
return res;// <- Here we construct the return value with res
}
// here we construct v with the return value of myVector:
vector<int> v = myVector();
l'elisione fuori dalla res
nel valore di ritorno di myVector
è un po 'fragile. In C++ 11, il move
che potrebbe verificarsi se elision fallisce sarà quasi altrettanto libero (come non fare nulla) - 3 copie puntatore e 3 cancella puntatore. In C++ 03, la copia che potrebbe verificarsi se elision fallisce può essere costosa (allocazione di memoria e copie O (n)).
Elision è il nome dell'operazione che i compilatori possono eseguire in determinate circostanze in cui due valori vengono trasformati in uno solo, anche se tale trasformazione causerebbe un cambiamento nel comportamento (cioè, fallisce il test as-if).
Quando ciò accade, il valore combinato ha una durata dell'unione delle due vite.
Nel caso precedente, la variabile locale res
e il valore di ritorno myVector()
possono essere eliminati dalla regola NRVO (denominata ottimizzazione del valore di ritorno). Il valore di ritorno di myVector
può essere eliminato in v
in quanto è una dichiarazione del modulo A a = b
dove b
è un'espressione che risulta in un valore anonimo (il nome di tali valori anonimi è stato modificato da C++ 03 a C++ 11 in modo Non lo userò), in particolare il valore di ritorno di myVector()
.
Ciò causa la durata di vita di res
v
e il valore di ritorno di myVector()
da unire in una durata di un valore. In pratica, ciò che accade è res
viene inserito direttamente nel punto in cui deve andare il valore di ritorno di myVector()
(in base alla convenzione di chiamata), e così è v
e la distruzione è di questo valore combinato saltato fino a quando v
non è più disponibile, come è in costruzione nell'istruzione return
e su v = myVector()
.
In altre parole, v
viene creato direttamente in myVector
.
In C++ 03, sono due copie, entrambe soggette ad elisione. In C++ 11, sono due mosse, entrambe soggette all'elisione. –
Perché ci sono due mosse? – Allanqunzi
La stessa ragione per cui ci possono essere due copie in C++ 03 - uno spostamento da 'res' nel valore di ritorno, e quindi uno spostamento da quello in' v'. –