1. "Що це?"
Хоча std::move()
технічно це функція - я б сказав, що це насправді не функція . Це свого роду перетворювач між способами компілятор вважає значення виразу.
2. "Що це робить?"
Перше, що слід зазначити, це те, std::move()
що насправді нічого не рухає . Він перетворює вираз із значення lvalue (наприклад, названої змінної) у xvalue . Значення xvalue повідомляє компілятору:
Ви можете пограбувати мене, перемістити все, що я тримаю, і використати його в іншому місці (оскільки я все одно незабаром буду знищений) ".
Іншими словами, коли ви використовуєте std::move(x)
, ви дозволяєте компілятору канібалізувати x
. Таким чином, якщо x
, скажімо, є власний буфер в пам'яті - після std::move()
того, як компілятор може мати власний інший об'єкт.
Ви також можете перейти від першого значення (наприклад, тимчасового, коли ви проїжджаєте), але це рідко корисно.
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 вказівника до буферів векторів плюс 3 розміри буферів. Звичайно, класу T
потрібно знати, як робити рухомий; ваш клас повинен мати оператора присвоєння переміщення та конструктора переміщення для класу, T
щоб це працювало.