c++11 右值引用

右值引用标记为T&&,在介绍右值引用前先了解什么是左值和右值。

左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时不再存在的临时对象。区分左右值,看能不能对表达式取地址,能取,是左值,不能取,是右值。所有具名变量或对象都是左值,而右值不具名。

c++11中右值两个概念,一个将亡值,另一个纯右值。非引用返回的临时变量、表达式产生的临时对象、原始字面量和lambda表达式等都是纯右值。将亡值是与右值引用相关的表达式,如将要被移动的对象、T&&函数返回值、std::move返回值和转换为T&&类型的转换函数的返回值。

T&&表示是一个未定的引用类型,如果&&被一个左值初始化,它就是一个左值;如果它被一个右值初始化,它就是一个右值。需要注意的是,只有发生自动类型推断时(如函数模板的类型自动推导,或auto关键字),&&才是一个未定的引用类型。

template<typename T>
void f(T&& param);            //T需要类型推断,&&是一个未定的引用类型

template<typename T>
class Test{
    Test(Test&& other);        //已经定义了一个特定的类型,没有类型推断,&&是一个右值引用
};

template<typename T>
void f(std::vector<T>&& param);        //&&是一个右值引用,在调用这个函数前,vector<T>中的推断类型已经确定了

template<typename T>
void f(const T&& param);            //&&是一个右值引用,未定的引用类型只在T&&下发生,任何一点附加条件都会使之失效

T&&未定的引用类型存在类型推导,相比右值引用(&&)会发生类型的变化,这种变化称为引用折叠。引用折叠的规则:

(1)所有的右值引用叠加到右值引用上仍然是一个右值引用。

(2)所有其它引用类型之间的叠加都将变成左值引用。

编译器会将已命名的右值引用视为左值,而将未命名的右值引用视为右值。

void PrintValue(int& i)
{
    cout << "lvalue:" << i << endl;
}

void PrintValue(int&& i)
{
    cout << "rvalue:" << i << endl;
}

void Forward(int&& i)            //i右值命名对象
{
    PrintValue(i);
}

int i = 0;
    PrintValue(i);        //lvalue:0
    PrintValue(1);        //rvalue:1
    Forward(2);            //lvalue:2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值