假设我们有一个函数
class Data
{
};
void func(Data && data)
{
}
那么func能接收什么样的参数输入
情形一
Data data;
func(data); //[Error] cannot bind 'Data' lvalue to 'Data&&'
data是个左值,不能绑定到右值上
情形二
Data data;
Data & d = data;
func(d); //[Error] cannot bind 'Data' lvalue to 'Data&&'
d同样是个左值
情形三
都说const 引用和 右值引用有相似之处,尝试传递const 引用
Data data;
const Data & d = data;
func(d); // [Error] invalid initialization of reference of type
// 'Data&&' from expression of type 'const Data'
情形四
传递匿名对象,匿名对象
func(Data()); // OK
情形五
标准做法
Data data;
func(std::move(data));//OK
情形六
move一个左值引用
Data data;
Data & p = data;
func(std::move(p)); //OK
情形七
直接声明一个右值引用,来做参数传递
Data p;
Data && p1 = std::move(p);
func(p1); // [Error] cannot bind 'Data' lvalue to 'Data&&'
同样的错误,说明p1 还是左值
我们可以通过这个方式验证一下
void func(Data && data)
{
}
void func_1(Data && data)
{
func(data);//[Error] cannot bind 'Data' lvalue to 'Data&&'
}
Data data;
func_1(std::move(data));
那么明明是个右值为什么,就变成左值了呢,这个时候就轮到 我们的std::forward出场了
Data p;
Data && p1 = std::move(p);
func(std::forward<Data>(p1)); // OK
void func_1(Data && data)
{
func(std::forward<Data>(data));
}
//这就是完美转发的意义所在
情形八
把一个右值参数传递给const 引用类型
void func(const Data & data)
{
}
void func_1(Data && data)
{
func(data);//OK
}
Data data;
func_1(std::move(data));