std::move: cast vô điều kiện một giá trị thành rvalue reference — cho phép move constructor/assignment "cướp" tài nguyên.
std::forward: cast có điều kiện — giữ nguyên value category (lvalue giữ lvalue, rvalue giữ rvalue) khi truyền tiếp vào hàm khác. Chỉ dùng với template forwarding reference (T&&).
Perfect forwarding pattern:
cpp
template <typename T>
void wrapper(T&& arg) {
// std::move(arg): luôn rvalue — có thể sai nếu arg là lvalue
// std::forward<T>(arg): đúng trong mọi trường hợp
doWork(std::forward<T>(arg));
}
std::string s = "hello";
wrapper(s); // arg là lvalue → forward giữ lvalue
wrapper(std::string{"world"}); // arg là rvalue → forward giữ rvalueQuy tắc:
- Dùng std::move khi bạn chắc chắn muốn move (biến local cuối cùng được dùng).
- Dùng std::forward trong template wrapper để không mất value category.
- Không dùng std::move trên function return value — RVO/NRVO hiệu quả hơn.