Я всегда помню lvalue как значение, которое имеет имя или может быть адресовано. Поскольку x имеет имя, оно передается как lvalue. Цель ссылки на rvalue - разрешить функции полностью clobber-значение любым способом, который он считает нужным. Если мы передадим x по ссылке, как в вашем примере, тогда у нас нет способа узнать, безопасно ли это сделать:
void foo(int &&) {}
void bar(int &&x) {
foo(x);
x.DoSomething(); // what could x be?
};
Выполнение foo(std::move(x));
явно сообщает компилятору, что вы сделали это с помощью x и больше не нуждается в этом. Без этого движения с существующим кодом могут случиться плохие вещи. std::move
является защитой.
std::forward
используется для идеальной пересылки в шаблонах.