左值、右值、将亡值 | 左值引用、右值引用
左值、右值、将亡值
左值、右值
左值(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")也属于左值。
常见的右值:除字符串以外的字面值,如3
、false
;返回非引用类型的函数调用;后置自增/自减运算符连接的表达式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]还分不清左值,右值,将亡值?看这里!
左值、右值、将亡值 | 左值引用、右值引用相关推荐
- C++11中的右值引用(对比左值引用和常引用)、移动构造函数和引用标识符
Hello!各位同学们大家好!逗比老师最近说起来还是挺尴尬的,为什么这么说呢?因为以前我对自己的C++水平还是相当自信的,经常以"精通"来自我评价.但是最近发现自己好像对C++11 ...
- [c++]-c++中的左值和右值、左值引用和右值引用、万能引用和引用折叠及完美转发
1.左值和右值 1.1左值和右值定义 在c++中,左值是一个指向内存的东西,换句话来讲,左值有地址,保存在内存中,右值则为不指向任何地方东西,即不在内存中占有确定位置.一般来说,右值是暂时和短暂的,而 ...
- 左值引用——右值引用 详解
顾明思议 左值引用 就是对左值的引用 就是给左值取别名 右值引用 就是对右值的引用 就是给右值取别名 当改变别名是 该值也相应的改变 那么 何以区分哪些是左值哪些是右值呢? 左值 右值 在内存中有特定 ...
- 判断是否左值引用/右值引用
判断是否左值引用/右值引用 有时候搞不清楚推导出来的类型是左值引用还是右值引用,可以用接口辅助判断: int i = 0; std::is_lvalue_reference<decltype(+ ...
- 深入浅出C++左值引用,右值引用,移动语义。
什么是左值 右值? 简单来说左值就是可以取地址,在=左边的,而右值就是不可以取地址,在=右边的. int t=10; t可以通过&取地址在=左边 所以t是左值 10不可以取地址 在=右边10是 ...
- c++ | 左值引用 右值引用
左值:可以取地址的.有名字的就是左值,比如 int a; 右值:不能取地址的是右值,表达式结束后就会被销毁, 比如 a*3 左值引用:就是普通引用,是为对象起的别名,必须被初始化,与变量绑定到一起 如 ...
- 左值/右值/左值引用/右值引用/move的用法介绍
目录 问题 左值和右值 概念总结: 需要用到左值的运算符: 引用分类 左值引用 右值引用 右值引用到底什么用? std::move()函数介绍 问题 什么是左值和右值? 什么是左/右值引用? 左/右值 ...
- std::move 左值右值 左值引用右值引用
参考:https://blog.csdn.net/daaikuaichuan/article/details/88371948 https://zhuanlan.zhihu.com/p/9458820 ...
- 2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码)
2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码) 1.引用(普通引用) 变量 ...
- item 24: 区分右值引用和universal引用
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 古人曾说事情的真相会让你觉得很自在,但是在适当的情 ...
最新文章
- C语言 学生宿舍管理系统
- Lync Server 2013 部署前端池支持NLB吗?
- 你很烫吗?我很烫——关于栈区和静态存储区的思考
- c语言超长编程程序,全国青少年软件编程等级考试C语言经典程序题10道五
- 大一新生开发的小工具火了!不一样的 Python 编程体验,还是可视化的那种
- asp.net core 3.0 更新简记
- JS 停留几秒后返回上一页
- xp搭建 php环境,windows xp 下 LAMP环境搭建
- linux重启was控制台报错,IHS启动时报错,从was控制台传播插件失败
- 雷军:执掌金山纯属意外
- 计算机硬件无法启动不能读取文件,修复Windows出现的“文件或目录已损坏且无法读取”问题...
- python-获取满足条件的索引值np.where
- Python:日期和时间类型学习
- JavaScript 3D 散点图
- SOUI自定义控件(3)
- 教你电脑系统如何深度清理c盘空间
- 卡巴斯基2010激活码
- html5 canvas 涂鸦画板
- KGB知识图谱完成金融行业的信息抽取工作
- Linux系统下LightDM详解