std::move
和 std::forward
是C++11中引入的两个模板函数,它们在C++的类型推导和完美转发中扮演着重要的角色。下面是它们之间的主要区别:
std::move
- 用途:
std::move
的主要用途是将一个左值转换为右值引用。这意味着它可以将一个对象的状态或资源从一个对象转移到另一个对象,而不需要进行复制。 - 效果:当你对一个对象使用
std::move
时,你是在告诉编译器,尽管这个对象是一个左值,你也可以像对待右值一样对待它,即可以从中移动资源。 - 返回类型:
std::move
返回的是参数的右值引用类型T&&
。 - 应用场景:常用于实现移动构造函数和移动赋值运算符,以及在其他需要转移资源所有权的场景。
std::forward
- 用途:
std::forward
的主要用途是在模板函数中保持参数的左右值属性不变。它是实现完美转发的基础,允许将参数(无论左值还是右值)透明地传递给其他函数。 - 效果:
std::forward
根据模板参数推导的结果,返回参数的原始引用类型(左值引用或右值引用)。 - 返回类型:
std::forward<T>
返回的是T&&
,这里的T
是模板参数,它会被推导为原始参数的引用类型。 - 应用场景:在模板函数中,尤其是那些需要将参数转发给其他函数的模板函数中。
-
// std::move 的例子 void process(int&& value) { // 使用 std::move 来转移 value 的所有权 } int x = 10; process(std::move(x)); // x 的值现在未定义 // std::forward 的例子 template<typename T> void wrapper(T&& arg) { process(std::forward<T>(arg)); // 保持 arg 的左右值属性 } int y = 20; wrapper(y); // y 作为一个左值传递给 wrapper,然后传递给 process wrapper(30); // 30 作为一个右值传递给 wrapper,然后传递给 process