1.«Что это?»
Хотя std::move()
технически является функцией - я бы сказал, это не на самом деле функция .Это своего рода конвертер между способами, которыми компилятор рассматривает значение выражения.
2.«Что он делает?»
Первое, что нужно отметить, это то, что std::move()
на самом деле ничего не двигает .Он преобразует выражение из lvalue (например, именованной переменной) в xvalue .Xvalue сообщает компилятору:
Вы можете грабить меня, переместить все, что у меня есть, и использовать его где-нибудь еще (поскольку в любом случае я скоро буду уничтожен) ".
другими словами, когда вы используете std::move(x)
, вы разрешаете компилятору каннибализировать x
. Таким образом, если x
имеет, скажем, свой собственный буфер в памяти - после std::move()
у компилятора может быть другой объект, которому он принадлежит.
Вы также можете перейти от prvalue (например, к временному объекту, который вы передаете), но это редкополезный.
3. «Когда его следует использовать?»
Еще один способ задать этот вопрос - «Для чего я мог бы уничтожить ресурсы существующего объекта?», хорошо, если выПри написании кода приложения, вы, вероятно, не будете много возиться с временными объектами, созданными компилятором. Поэтому, в основном, вы будете делать это в таких местах, как конструкторы, методы операторов, функции, аналогичные алгоритму стандартной библиотеки и т. д., куда попадают объектысоздал и уничтожил автОмагически много.Конечно, это всего лишь практическое правило.
Типичное использование - это «перемещение» ресурсов с одного объекта на другой вместо копирования.@Guillaume ссылается на эту страницу , на которой есть простой короткий пример: замена двух объектов с меньшим количеством копий.
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)
}
с помощью перемещения позволяет вам менять ресурсы вместо их копирования:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Подумайте о том, что происходит, когда T, скажем, vector<int>
размера n.В первой версии вы читаете и пишете 3 * n элементов, во второй версии вы в основном читаете и записываете только 3 указателя на буферы векторов.Конечно, класс T должен знать, как сделать движение;Ваш класс должен иметь оператор присваивания перемещения и конструктор перемещения для класса T, чтобы это работало.