总结:
C++11中所有的值属于左值,右值两者之一。
左值引用:指的是可以放在赋值表达式左边的事物——在堆上或者栈上分配的命名对象或者其他对象成员——有明确的内存地址。
对左值的const引用创建临时性对象,作为参数传递给函数:
void print(std::string const&) ; print("hello"); //创建了临时std::string对象
右值:函数int fun()的返回值是右值,在其被赋给某一变量前,我们不能通过变量名来找到它。
右值分为纯右值和将亡值:
纯右值:临时变量和不跟对象关联的字面量值
将亡值:在确保其他变量不再被使用或即将销毁时,通过盗取的方式,可以避免内存空间的释放和分配,能够延长变量值的生命期。
右值通常不具有名字,也只能通过引用的方式找到它的存在。
引用类型本身并不拥有所绑定对象的内存,只是该对象的一个别名。
左值引用是具名变量值的别名,右值引用是不具名(匿名)变量的别名。
常量左值引用是个万能引用类型,可接受常量左值(带有const),非常量左值和右值对其初始化。
常量左值引用的右值在其“余生”只能是只读的
int &a = 2; # 左值引用绑定到右值,编译失败
int b = 2; # 非常量左值
const int &c = b; # 常量左值引用绑定到非常量左值,编译通过
const int d = 2; # 常量左值
const int &e = c; # 常量左值引用绑定到常量左值,编译通过
const int &b =2; # 常量左值引用绑定到右值,编程通过
右值引用通常不能绑定到任何的左值,要想绑定一个左值到右值引用,通常需要std::move()将左值强制转换为右值。
int a;
int &&r1 = c; # 编译失败
int &&r2 = std::move(a); # 编译通过
引自:https://blog.csdn.net/hyman_yx/article/details/52044632