1 首先: C++ 11通过右值引用来优化性能, 就是通过移动的语义来避免拷贝,通过move语义来将临时生成的左值中的资源无代价的转移到另一个对象中去,解决了不能按照实际类型来转发的问题。
2 C++中所有的值必是左值和右值之一,右值又可以分为: 纯右值和将亡值
左值: 有地址的的,有名字的, 通常出现在赋值语句的左边, 但是const int & a = 10 只能取地址,不能赋值
右值: 不能取地址的,没有名字的 比如表达式 b + c, int func(x);如常量值,函数的返回值, lambda表达式等,无法获取地址,但不表示他不可改变 可以通过获取右值的右值引用时可以更改右值。
细分的话:
纯右值:::指的是临时变量和不跟对象关联的字面量值
将亡值:::指的是跟右值引用相关的表达式,通常是将要被移动的对象, 比如 返回右值引用的相关的表达式
还可以将其理解为在确保其他变量不在使用,或即将销毁的时候,通过盗取的方式 可以避免内存空间的释放和分配,能够延长变量值得生命周期。
3 无论左值引用还是右值引用 都必须立即初始化, 原因是引用的是其他变量的别名, 必须绑定到其他对象上,本身并不拥有所绑定对象的内存空间。
::右值虽然无法获取地址, 可通过右值引用关联到右值, 右值被存储到特定的位置, ::右值引用指向特定的位置,右值虽然无法获取地址,但是右值引用可以获取地址,该地址表示临时对象的存储位置。
左值引用是具名变量值的别名,而右值引用是匿名变量的别名,
非常量左值引用 不能绑定到 右值,只能绑定非常量左值
但是常量左值引用可以绑定非常量左值, 常量左值, 右值对其进行初始化,但引用的右值在之后只能是只读的
4 右值引用通常不能绑定到任何的左值, 要想绑定一个左值到右值的引用, 右值引用能够通过std::move() 将左值强制转换为右值。