一.什么是左值右值
一般来说能取地址的,也就是等号左边的值,比如创建的int变量是左值,而右值就是与他相反, 在等号右边,并且不能被取地址,比如说数字10。一般的普通引用只能引用左值。引用和const组合在一起使用的话既可以引用左值也可以引用右值。右值引用可以引用右值,也可以引用move后的左值
二.为们要存在右值
我们都知道,使用在传参数或者返回值的时候使用左值在一般情况下能很好的减少拷贝提升效率。但在有些情况,左值并不能起到很好的作用。比如说在模拟实现to_string的时候,返回值不可以作为引用返回,因为是临时变量,如果在传入参数的时候使用引用作为输出型参数的话又不符合我们的引用习惯。这个时候就能用到右值引用,右值引用并不是直接使用的而是嵌套在移动构造和移动赋值中使用的。
三.移动构造
移动构造实现的本质就是让旧的资源从旧的对象上移动到新的对象上。通常情况下(不考虑系统优化),当我们返回将亡值(即将销毁的值,因为是函数体内部创建的临时变量)的时候需要先要调用一次拷贝函数将返回值拷贝到一个临时变量上,再将临时变量的值拷贝到主函数的对象上。而在c++11中。会将这种右值进行移动构造,将这个值和临时变量的值进行交换,再调用构造函数将临时变量的值和主函数的值进行交换。因为是将亡值,所以即使发生交换也不会有什么影响。从而能较少拷贝构造,大大提升效率,移动赋值和移动构造同理。
四.万能引用和完美转发
因为右值引用既可以接受左值也能接受右值,所以用右值引用作为形参又称作万能引用。但是这又会引发一种叫做引用折叠的问题,不管是左值还是右值,经过万能引用后,在函数体内部调用的时候都变为了左值,这时候如果在这个函数体内部在调用就有可能产生问题,为了让他保持原先的属性状态,我们需要使用forward函数来实现完美转发,从而保持原来的左值或者右值属性