左值、右值、左值引用和右值引用

news2024/11/26 0:29:57

左值、右值和左值引用,在C++11之前,我们都很熟悉也都很好理解。左值(LValue)就是有名字能够寻址的对象的值类型,右值就是在内存上没有名字的数值的值类型,左值引用就是指向左值的引用。

C++11引入了右值引用,从而可以去读写在内存上临时的右值(C++11之前可以使用const左值引用去指向右值来读右值的内容,但是无法修改所指向的右值内容)。

C++11之前,任何对象不是左值就是右值,那引入右值引用之后,右值引用到底是左值还是右值呢?考虑到右值引用在行为使用上与右值有相似的地方,但也有冲突的地方,具体细节可以参考C++标准文档(n3055)。于是C++标准委员会将原来非黑即白的左值和右值两种类型细分成了5种类别,其中一些类别还会有共同重叠的部分。这5种类别中最值的关注的就是新创建了XValue,C++标准规定将一个右值引用绑定到一个对象,这个行为或者说是这个表达式的结果就是XValue。可见,XValue的诞生就是为右值引用量身定制的。那XValue这个名字起源于eXpiring这个单词,其实也很好理解,当我们使用一个右值引用想要move一个临时对象的值时,这个临时对象的生命周期也就即将结束。

除了XValue,另外4中类型分别是LValue, GLValue,RValue和PRValue。LValue还是传统意义上的左值。GLValue是generalized LValue,它包括LValue和XValue。PRValue是pure RValue,虽然是新的类型,但它就是之前传统意义上的右值。RValue现在是一个统称,它包括PRValue和XValue。具体包含关系可以见下图:

需要注意的是,XValue它既是GLValue,也是RValue,所以这里是的关系。 

从图中可以看出,C++11之后,任何一个值,它肯定是LValue,XValue和PRValue中的一种。LValue和PRValue,我们都很好理解,那XValue到底会在哪些情况下出现用到呢?

C++标准规定了以下这些情况下的表达式的结果都是XValue:

  • 无论是显式还是隐式调用一个函数,只要函数返回值的类型是指向对象的右值引用,那么调用的结果就是XValue;
  • 将现有的对象转换成指向对象的右值引用,这个行为或者叫表达式的结果就是XValue;
  • 如果一个对象本身已经是XValue,那访问这个对象的非static的成员变量的表达式的结果就是XValue;
  • 如果一个对象本身已经是XValue,并且通过.*pointer-to-member的方式来访问成员变量,那这个表达式的结果就是XValue

总而言之,以上这些规则表明,有名字的(named)右值引用将会被视为左值没名字的(unnamed)右值引用将会被视为XValue。下面是这些规则的一个例子:

struct A {
    int m;
};

A&& operator+(A, A);
A&& f();

A a;
A&& ar = static_cast<A&&>(a);

表达式f(),表达式f().m,表达式static_cast<A&&>(a),表达式 a + a,以上这些表达式的结果都是XValue。表达式ar是一个左值,它的类型是A。根据文档中的解释,如果一个表达式是一个指向类型T的引用,那么这个表达式的类型将会调整为类型T。

上面的例子中static_cast<A&&>(a)是XValue,而std::move的实现正是使用了static_cast<X&&>:

template<typename T> struct remove_reference { typedef T type; };
template<typename T> struct remove_reference<T&> { typedef T type; };
template<typename T> struct remove_reference<T&&> { typedef T type; };

template<typename T>
constexpr typename remove_reference<T>::type && move(T && arg) noexcept
{
  return static_cast<typename remove_reference<T>::type &&>(arg);
}

所以,std::move的返回值是一个XValue,而XValue也是一个右值,所以std::move的返回值也是一个右值,这也是为什么使用std::move可以触发调用move constructor/assignment,而不是调用copy constructor/assignment:

struct X
{
  std::string s_;

  X(){}

  X(const X & other) : s_{ other.s_ } {}

  X(X && other) noexcept : s_{ std::move(other.s_) } {}
  // other is an lvalue, and other.s_ is an lvalue too
  // use std::move to force using the move constructor for s_
  // don't use other.s_ after std::move (other than to destruct)
};

int main()
{
  X a;

  X b = std::move(a);
  // a is an lvalue
  // use std::move to convert to a rvalue,
  // xvalue to be precise,
  // so that the move constructor for X is used
  // don't use a after std::move (other than to destruct)
}

参考资料:

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3055.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070873.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

奔驰与蔚来,“联姻”只是传闻?

继比亚迪与丰田&#xff0c;小鹏汽车与大众&#xff0c;零跑汽车与Stellantis陆续展开或传出合作机会之后&#xff0c;近日蔚来也被曝出正在与奔驰进行合作洽谈。 这意味着&#xff0c;在新能源尤其是智能电动时代&#xff0c;传统外资车企占据技术主动权&#xff08;所谓的技术…

HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Span

作为Text组件的子组件&#xff0c;用于显示行内文本的组件。无子组件 一、接口 Span(value: string | Resource) 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 参数&#xff1a; 参数名 参数类型 必填 参数描述 value string | Resource 是 文本内…

主流的图像—文本的多模态技术实现方法有哪些?

大体上可划分为3类&#xff1a; 1&#xff09;训练中间层以对齐视觉模块和语言模型。该类方法首先预训练视觉模块&#xff0c;将这些视觉模块与LLM冻结&#xff0c;然后在视觉模块与LLM之间插入可训练的中间层&#xff0c;构建多模态模型。接着在大规模的图像—文本对数据集上…

基于SSM的实验室考勤管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

项目总监必看:如何利用Git深度统计团队代码贡献?多语言实践教程揭秘!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

AP5193 DC-DC降压恒流驱动器 大功率宽电压LED驱动IC

产品描述 AP5193是一款PWM工作模式,高效率、简单、内置功率MOS管&#xff0c;适用于4.5-100V输入的高精度降压LED恒流驱动芯片。电流2.5A。AP5193可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5193 工作频率可以通过RT 外部电阻编程来设定&#xff…

ffprobe命令

查看一个音频文件&#xff0c;在终端命令行输入一下命令 ffprobe video/audio.m4a 可以看到audio.m4a这个文件的所有信息。 Duration&#xff1a;音频总时长&#xff1a;开始播放时间&#xff1a;比特率 Stream&#xff1a;说明是一个音频流&#xff0c;编码格式是aac&…

珠宝饰品商家为什么要做微信小程序开发

珠宝饰品商家为什么要做微信小程序开发&#xff1f; 随着互联网的发展&#xff0c;微信小程序作为一种新型的应用形态&#xff0c;正逐渐成为商家们关注的热点。对于珠宝饰品商家来说&#xff0c;开发微信小程序具有以下几个方面的优势&#xff1a; 一、获取更多流量 微信小程…

浅谈霍尔传感器在电子设备中的应用

安科瑞虞佳豪壹捌柒陆壹伍玖玖零玖叁 0摘 要&#xff1a;本文介绍了霍尔传感器的原理、应用和发展情况&#xff0c;详细讨论了其在电子设备中的应用。霍尔传感器在电子设备中具有高精度、高灵敏度、高稳定性等特点&#xff0c;可以应用于磁场测量、位置检测、电流检测等多个领…

zookeeper入门篇之分布式锁

文章目录 前言非公平锁公平锁 前言 上一篇说过&#xff0c;zookeeper是一个类似文件系统的数据结构&#xff0c;每个节点都可以看做是一个文件目录&#xff0c;也就是说&#xff0c;我们所创建的节点是唯一的&#xff0c;那么分布式锁的原理就是基于这个来的。 代码仓库&…

196、管理 RabbitMQ 的用户

开启Rabbitmq的一些命令&#xff1a; 小黑窗输入&#xff1a; rabbitmq-plugins enable rabbitmq_management 启动控制台插件&#xff0c; 就是启动登录rabbitmq控制台的页面&#xff0c;rabbitmq_management 代表了RabbitMQ的管理界面。 rabbitmq-server 启动rabbitMQ服务器…

NoSQL Redis

NoSQL Redis 1、数据库1.1关系型数据库1.2非关系型数据库1.3关系型和非关系型区别 2、非关系型数据库应用场景3、存储结构4、redis4.1redis概述4.2Redis 优点4.3Redis为什么这么快&#xff1f; 5、部署redis6、redis基础操作 1、数据库 1.1关系型数据库 关系型数据库是一个结…

房地产行业如何有效进行软文推广?

对于房地产行业来说&#xff0c;软文营销是常见的营销方式&#xff0c;也有不少地产行业来找媒介盒子进行软文推广&#xff0c;和传统的硬广相比&#xff0c;软文成本更低&#xff0c;而且效果是持续性的&#xff0c;那么房地产行业如何有效进行软文推广呢&#xff1f;接下来就…

Stable Diffusion生成图片

画质 masterpiece,best quality,illustration,extremely detail CG unity 8k wallpaper,ultra-detailed,depth of field 杰作&#xff0c;最佳质量&#xff0c;插图&#xff0c;极度详细的8K壁纸&#xff0c;超高详细度&#xff0c;景深 画风 Chinese ink painting,water color…

一文弄懂 if __name__ == “__main__“:(洒洒水啦!)

本篇文章是博主在AI、无人机、强化学习等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在AI学…

C#练习题-构造函数

文章目录 前言题目习题1运行示例 习题2运行示例 参考答案习题1习题2 其他文章 前言 本篇文章的题目为C#的基础练习题&#xff0c;构造函数部分。做这些习题之前&#xff0c;你需要确保已经学习了构造函数的知识。 本篇文章可以用来在学完构造函数后加深印象&#xff0c;也可以…

在JavaScript中,什么是生成器函数(generator function)?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 生成器函数概述⭐ 生成器函数的作用⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域…

嵌入式开发系统中的加密性能:第1部分

嵌入式系统上的密码学基础密码术是处理数据的艺术和科学&#xff0c;因此外部团体在没有任何秘密的情况下就无法撤消或模仿该操作。它启用了高级功能&#xff0c;例如&#xff1a; 存储和传输期间信息的机密性 用户身份验证 接收/检索的信息的完整性 不可否认交易的 有效性…

美女制服扮演建模法-UMLChina建模知识竞赛第4赛季第13轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。第4题为附加题&#xff0c;对错不影响优胜者…

2023年中国家用路由器市场发展概况分析:家用路由器线上市场整体销量为1050.6万台[图]

在疫情过后的第一个半年度&#xff0c;已经连续三年规模下滑幅度超过15%的家用路由器行业&#xff0c;终于迎来一丝回暖迹象。2023年上半年&#xff0c;我国家用路由器线上市场整体销量为1051万台&#xff0c;同比下降5.5%&#xff0c;下降幅度开始收窄&#xff0c;销售额为24.…