左值、右值、将亡值

左值、右值

左值(lvalue)中l指的是location,是有明确地址的,可寻址的值。右值(rvalue)中r指的是read,是可读的值,不一定可以寻址。左值可以当右值使用,但右值不一定能当左值使用。如:

int n = 10;
n = 20;        //正确,n为左值,20为右值
20 = n;        //错误int m = 5;
n = m;     //正确

常见的左值:函数名和变量名(实际上是函数指针和具名变量,具名变量如std::cin、std::endl等);返回左值引用的函数调用;前置自增/自减运算符连接的表达式++i/–i;由赋值运算符或复合赋值运算符连接的表达式(a=b、a+=b、a%=b);解引用表达式*p。注意:字符串字面值(如"abc")也属于左值

常见的右值:除字符串以外的字面值,如3false;返回非引用类型的函数调用;后置自增/自减运算符连接的表达式i++/i–;lambda表达式;算术表达式(a+b、a&b、a<<b)、逻辑表达式(a&&b、a||b、~a)、比较表达式(a==b、a>=b、a<b)、取地址表达式(&a)等。

将亡值

C++11中,右值被分为纯右值(prvalue,即pure rvalue)和将亡值(xvalue,即expiring value),左值和将亡值被统称为泛左值(glvalue,即generalized lvalue,也称广义左值)。C++11中一个值只可能是lvalue、xvalue、prvalue中的一种。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-imHmsw5J-1663437222462)(https://img1.imgtp.com/2022/09/17/EB6OBnKI.png)]

C++11前右值和C++11中的纯右值是等价的。C++11中的将亡值是随着右值引用的引入而新引入的。换言之,“将亡值”概念的产生,是由右值引用的产生而引起的,将亡值与右值引用息息相关。所谓的将亡值表达式,就是下列表达式:

  • 返回右值引用的函数的调用表达式
  • 转换为右值引用的转换函数的调用表达式

在C++11中,我们用左值去初始化一个对象或为一个已有对象赋值时,会调用拷贝构造函数或拷贝赋值运算符来拷贝资源(所谓资源,就是指new出来的东西),而当我们用一个右值(包括纯右值和将亡值)来初始化或赋值时,会调用移动构造函数或移动赋值运算符来移动资源,从而避免拷贝,提高效率。当该右值完成初始化或赋值的任务时,它的资源已经移动给了被初始化者或被赋值者,同时该右值也将会马上被销毁(析构)。也就是说,当一个右值准备完成初始化或赋值任务时,它已经“将亡”了。而上面两种表达式的结果都是不具名的右值引用,它们属于右值。又因为

  • 这种右值是与C++11新生事物——“右值引用”相关的“新右值”
  • 这种右值常用来完成移动构造或移动赋值的特殊任务,扮演着“将亡”的角色

所以C++11给这类右值起了一个新的名字——将亡值。

常见的将亡值:返回值为右值引用的函数调用;std::move(x)a.m其中a是一个右值,m是一个非引用类型的非静态数据成员;a.*mp其中a是一个右值,mp是一个指向数据成员的指针;对象类型的右值引用的强制转换表达式,例如static_cast<char&&>(x)

注意

字符串字面值是左值cout << &("abc") << endl;这条语句在各个版本的编译器上均可以编译通过。

左值引用、右值引用

左值引用就是C++11前的引用,顾名思义是对左值的引用。左值引用以&作为限定符:

int num = 10;
int &a = num; //正确
int &b = 10; //错误,10是纯右值

右值引用在C++11标准被引入,以&&作为限定符:

int num = 10;
int && b = num;  //错误,右值引用不能初始化为左值
int && a = 10; //正确a = 11;        //右值引用可以修改右值
cout << a << endl;   //输出结果为11

**注意!**具名的右值引用是左值,不具名的右值引用是右值(type_to_string()返回指示表达式的类型的字符串,详见怎么知道一个表达式是啥类型的值?):

int&& get_a_int() {return 0;
}//get_a_int()的返回值是一个不具名的右值引用
std::cout << "The type of get_a_int() : " << type_to_string<decltype(get_a_int())>() << std::endl;
std::cout << "The value type of get_a_int() : " << type_to_string<decltype((get_a_int()))>() << std::endl;//get_a_int()返回值被赋值给右值引用类型变量n,这里的n就是一个具名的右值引用
int&& n = get_a_int();
std::cout << "The type of n : " << type_to_string<decltype(n)>() << std::endl;
std::cout << "The value type of n : " << type_to_string<decltype((n))>() << std::endl;

输出:

The type of get_a_int() : int&&
The value type of get_a_int() : int&&
The type of n : int&&
The value type of n : int&

参考文章

[1]还分不清左值,右值,将亡值?看这里!

左值、右值、将亡值 | 左值引用、右值引用相关推荐

  1. C++11中的右值引用(对比左值引用和常引用)、移动构造函数和引用标识符

    Hello!各位同学们大家好!逗比老师最近说起来还是挺尴尬的,为什么这么说呢?因为以前我对自己的C++水平还是相当自信的,经常以"精通"来自我评价.但是最近发现自己好像对C++11 ...

  2. [c++]-c++中的左值和右值、左值引用和右值引用、万能引用和引用折叠及完美转发

    1.左值和右值 1.1左值和右值定义 在c++中,左值是一个指向内存的东西,换句话来讲,左值有地址,保存在内存中,右值则为不指向任何地方东西,即不在内存中占有确定位置.一般来说,右值是暂时和短暂的,而 ...

  3. 左值引用——右值引用 详解

    顾明思议 左值引用 就是对左值的引用 就是给左值取别名 右值引用 就是对右值的引用 就是给右值取别名 当改变别名是 该值也相应的改变 那么 何以区分哪些是左值哪些是右值呢? 左值 右值 在内存中有特定 ...

  4. 判断是否左值引用/右值引用

    判断是否左值引用/右值引用 有时候搞不清楚推导出来的类型是左值引用还是右值引用,可以用接口辅助判断: int i = 0; std::is_lvalue_reference<decltype(+ ...

  5. 深入浅出C++左值引用,右值引用,移动语义。

    什么是左值 右值? 简单来说左值就是可以取地址,在=左边的,而右值就是不可以取地址,在=右边的. int t=10; t可以通过&取地址在=左边 所以t是左值 10不可以取地址 在=右边10是 ...

  6. c++ | 左值引用 右值引用

    左值:可以取地址的.有名字的就是左值,比如 int a; 右值:不能取地址的是右值,表达式结束后就会被销毁, 比如 a*3 左值引用:就是普通引用,是为对象起的别名,必须被初始化,与变量绑定到一起 如 ...

  7. 左值/右值/左值引用/右值引用/move的用法介绍

    目录 问题 左值和右值 概念总结: 需要用到左值的运算符: 引用分类 左值引用 右值引用 右值引用到底什么用? std::move()函数介绍 问题 什么是左值和右值? 什么是左/右值引用? 左/右值 ...

  8. std::move 左值右值 左值引用右值引用

    参考:https://blog.csdn.net/daaikuaichuan/article/details/88371948 https://zhuanlan.zhihu.com/p/9458820 ...

  9. 2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码)

    2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码) 1.引用(普通引用) 变量 ...

  10. item 24: 区分右值引用和universal引用

    本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 古人曾说事情的真相会让你觉得很自在,但是在适当的情 ...

最新文章

  1. C语言 学生宿舍管理系统
  2. Lync Server 2013 部署前端池支持NLB吗?
  3. 你很烫吗?我很烫——关于栈区和静态存储区的思考
  4. c语言超长编程程序,全国青少年软件编程等级考试C语言经典程序题10道五
  5. 大一新生开发的小工具火了!不一样的 Python 编程体验,还是可视化的那种
  6. asp.net core 3.0 更新简记
  7. JS 停留几秒后返回上一页
  8. xp搭建 php环境,windows xp 下 LAMP环境搭建
  9. linux重启was控制台报错,IHS启动时报错,从was控制台传播插件失败
  10. 雷军:执掌金山纯属意外
  11. 计算机硬件无法启动不能读取文件,修复Windows出现的“文件或目录已损坏且无法读取”问题...
  12. python-获取满足条件的索引值np.where
  13. Python:日期和时间类型学习
  14. JavaScript 3D 散点图
  15. SOUI自定义控件(3)
  16. 教你电脑系统如何深度清理c盘空间
  17. 卡巴斯基2010激活码
  18. html5 canvas 涂鸦画板
  19. KGB知识图谱完成金融行业的信息抽取工作
  20. Linux系统下LightDM详解

热门文章

  1. deepin linux mysql工具
  2. 买二手房防骗攻略 ,让我们一起饿死无良中介
  3. AVFoundation的介绍
  4. 【无标题】学习笔记-2022.8.1-8.6
  5. Flutter完整开发实战详解(十七、 实用技巧与填坑二)
  6. IDEA+Marven 整合ssm框架实现
  7. Office 365组命名策略 - 概述
  8. 钢筋盘点计数数据集图片展示
  9. 树莓派buster版本-中科大源配置
  10. SX1276 FSK模式下的空中耗时计算