1. "Qu'est-ce que c'est?"
Bien que ce std::move()
soit techniquement une fonction - je dirais que ce n'est pas vraiment une fonction . C'est une sorte de convertisseur entre les façons dont le compilateur considère la valeur d'une expression.
2. "Que fait-il?"
La première chose à noter est que std::move()
rien ne bouge réellement . Il convertit une expression qui est une lvalue (telle qu'une variable nommée) en une xvalue . Une valeur x indique au compilateur:
Vous pouvez me piller, déplacer tout ce que je tiens et l'utiliser ailleurs (car je vais bientôt être détruit) ".
en d'autres termes, lorsque vous utilisez std::move(x)
, vous autorisez le compilateur à cannibaliser x
. Ainsi, si x
a, disons, son propre tampon en mémoire - après std::move()
ing le compilateur peut avoir un autre objet le posséder à la place.
Vous pouvez également passer d'une valeur (telle qu'une valeur temporaire que vous passez), mais cela est rarement utile.
3. "Quand faut-il l'utiliser?"
Une autre façon de poser cette question est la suivante: "Pourquoi cannibaliser les ressources d'un objet existant?" eh bien, si vous écrivez du code d'application, vous ne vous amuseriez probablement pas beaucoup avec des objets temporaires créés par le compilateur. Donc, vous le feriez principalement dans des endroits comme les constructeurs, les méthodes d'opérateur, les fonctions de type algorithme de bibliothèque standard, etc. Bien sûr, ce n'est qu'une règle d'or.
Une utilisation typique consiste à «déplacer» des ressources d'un objet à un autre au lieu de les copier. @Guillaume renvoie à cette page qui a un court exemple simple: échanger deux objets avec moins de 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)
}
utiliser move vous permet d'échanger les ressources au lieu de les copier:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Pensez à ce qui se passe quand T
, disons, vector<int>
de taille n. Dans la première version, vous lisez et écrivez 3 * n éléments, dans la deuxième version, vous lisez et écrivez simplement les 3 pointeurs vers les tampons des vecteurs, plus les 3 tailles des tampons. Bien sûr, la classe T
doit savoir comment bouger; votre classe doit avoir un opérateur d'affectation de mouvement et un constructeur de mouvement pour que la classe T
fonctionne.