1. "Che cos'è?"
Anche std::move()
se tecnicamente è una funzione, direi che non è davvero una funzione . È una specie di convertitore tra i modi in cui il compilatore considera il valore di un'espressione.
2. "Che cosa fa?"
La prima cosa da notare è che in std::move()
realtà non sposta nulla . Converte un'espressione da essere un valore (come una variabile denominata) in un valore x . Un xvalue dice al compilatore:
Puoi saccheggiarmi, spostare tutto ciò che tengo in mano e usarlo altrove (dato che comunque sarò distrutto presto) ".
in altre parole, quando usi std::move(x)
, stai permettendo al compilatore di cannibalizzare x
. Quindi, se x
ha, diciamo, il suo buffer in memoria - dopo std::move()
ing il compilatore può avere un altro oggetto al suo posto.
Puoi anche spostarti da un valore (come un temporaneo che stai passando), ma questo è raramente utile.
3. "Quando dovrebbe essere usato?"
Un altro modo di porre questa domanda è "Per cosa dovrei cannibalizzare le risorse di un oggetto esistente?" bene, se stai scrivendo il codice dell'applicazione, probabilmente non ti sbaglierebbe molto con gli oggetti temporanei creati dal compilatore. Quindi principalmente lo faresti in luoghi come costruttori, metodi di operatore, funzioni simili a algoritmi di libreria standard ecc. In cui gli oggetti vengono creati e distrutti molto automagicamente. Certo, questa è solo una regola empirica.
Un uso tipico è lo "spostamento" delle risorse da un oggetto a un altro anziché la copia. @Guillaume collega a questa pagina che ha un breve esempio semplice: scambiare due oggetti con meno copie.
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
l'utilizzo di move ti consente di scambiare le risorse invece di copiarle:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Pensa a cosa succede quando T
, diciamo, vector<int>
della taglia n. Nella prima versione leggi e scrivi elementi 3 * n, nella seconda versione fondamentalmente leggi e scrivi solo i 3 puntatori ai buffer dei vettori, più le dimensioni dei 3 buffer. Naturalmente, la classe T
deve sapere come muoversi; la tua classe dovrebbe avere un operatore di assegnazione di mosse e un costruttore di mosse affinché la classe T
funzioni.