左值、右值、亡值,纯右值,左值引用,右值引用
杂项01.png

概念

左值:具有存储地址,可以被赋值和修改

1
int a = 10;

右值:无存储地址,是表达式的临时值

1
a + 530

将亡值:即将被销毁的对象

1
2
3
std::move(str)

这个时候的 str 就是将亡值,因为 move 之后 当前作用域下 str 将不能被使用,因为资源已经移动,再使用就出现未定义行为

纯右值:值本身,字面值或临时对象的计算结果

满足下列条件之一

  • 本身就是赤裸裸的、纯粹的字面值,如20、false
  • 求值结果相当于字面值或是一个不具名的临时对象,如 x + 5
1
x + 520false

左值引用:用于绑定到左值的引用

1
int& ref = a;

右值引用:用于绑定到右值的引用,支持移动语义

1
std::string&& r = std::move(str);

特别说明

不是所有的字面值都是纯右值,字符串字面值是唯一例外。

早期 C++ 将字符串字面值实现为 char 型数组,实实在在地为每个字符都分配了空间并且允许程序员对其进行操作,所以类似:

1
2
cout<<&("abc")<<endl;
char *p_char="abc";//注意不是char *p_char=&("abc");

 

T& 只能绑定非常量左值。

const T& 是万能引用类型,可以绑定任意值类别的表达式。

T&& 只能绑定非常量右值。

const T&& 能绑定右值类型的表达式,无论是否常量。

杂项02.png

 

准确的来说,所有的引用,无论是左值引用还是右值引用,都是左值表达式。

这是因为右值引用延长了右值的生命周期,我们可以去取右值引用的地址,因此它是个左值。

 

move 虽然将左值转换成了右值,但其生命周期并不会像右值一样立即结束,而是转移了。

参考链接

https://www.cnblogs.com/zpcdbky/p/5275959.html

https://blog.csdn.net/yuejisuo1948/article/details/117048660

https://en.cppreference.com/w/cpp/language/value_category