std::move和std::forward本质就是一个转换函数,std::move执行到右值的无条件转换,std::forward执行到右值的有条件转换,在参数都是右值时,二者就是等价的
一、完美转发 std::forward
std::forward是一个模板函数,实现了参数在传递过程中保持其值属性的功能,模板参数决定了它返回的是左值还是右值。
二、移动语义 std::move
std::move的作用就是用来将一个左值强制转换为右值
std::move()使用前提:
1 定义的类使用了资源并定义了移动构造函数和移动赋值运算符
2 该变量即将不再使用
在需要改变一个资源的拥有者时都可以使用std::move。一般情况下move都是用来处理临时对象的,因为对一个对象使用move语句后,该对象将会变为一个不合法的东西。对没有定义移动构造函数等的对象,使用move仍会发生拷贝,例如基本类型(int,float等),不要以下面的方式使用move
Object n;
auto x = std::move(n);
auto y = n; //此时的n已经被move掏空了,是一个非法对象,forward也不能这样使用
注意和算法库<algorithm>中的std::move的区别
三、示例代码
点击查看代码
#include <iostream>
void fun(int&& n)
{
std::cout << "右值\n";
}
void fun(int& n)
{
std::cout << "左值\n";
}
int main()
{
int ln1 = 9;
int ln2 = 6;
int ln3 = 3;
int ln4 = 1;
int&& rn1 = 8;
int&& rn2 = 7;
int&& rn3 = 6;
int&& rn4 = 5;
fun(std::move(rn1)); //右值
fun(std::forward<int>(rn2)); //右值
fun(std::forward<int&>(rn3));//左值
std::cout << "===\n";
fun(std::move(ln1)); //右值
fun(std::forward<int&>(ln2)); //左值
fun(std::forward<int>(ln3)); //右值
std::cout << "***\n";
fun(2); // 右值
fun(ln4); // 左值
fun(rn4); // 左值
return 0;
}
四、五法则
任何想要移动语义的类必须声明全部五个特殊成员函数:
-
拷贝构造函数(copy constructor)
-
移动构造函数(move constructor)
-
拷贝赋值运算符(copy-assignment operator)
-
移动赋值运算符(move-assignment operator)
-
析构函数 (destructor)