C++11:右值引用

news2024/10/6 22:25:37

文章目录

  • 1. C++左值和右值
  • 2. C++右值引用

右值引用是一种新的 C++ 语法,基于右值引用引申出了 2 种 C++ 编程技巧,分别为移动语义和完美转发。本文主要介绍什么是右值引用以及它的基本用法。

1. C++左值和右值

右值引用可以从字面意思上理解,指的是以引用传递(而非值传递)的方式使用 C++ 右值。在 C++ 或者 C 语言中,一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式和右值表达式。确切的说 C++ 中左值和右值的概念是从 C 语言继承过来的。

左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是"left value"、“right value” 的缩写,其实不然。lvalue 是“loactor value”的缩写,意为存储在内存中、有明确存储地址(可寻址)的数据,而 rvalue 译为 “read value”,指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。

通常情况下,判断某个表达式是左值还是右值,有以下 2 种方法:

  1. 可位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值。举个例子:
int a = 5;
5 = a; // 错误,5 不能为左值

其中,变量 a 就是一个左值,而字面量 5 就是一个右值。C++ 中的左值也可以当做右值使用,例如:

int b = 10; // b 是一个左值
a = b; // a、b 都是左值,只不过将 b 可以当做右值使用
  1. 有名称的、可以获取到存储地址的表达式即为左值;反之则是右值。

以上面定义的变量 a、b 为例,a 和 b 是变量名,且通过 &a 和 &b 可以获得他们的存储地址,因此 a 和 b 都是左值;反之,字面量 5、10,它们既没有名称,也无法获取其存储地址(字面量通常存储在寄存器中,或者和代码存储在一起),因此 5、10 都是右值。

注意,以上 2 种判定方法只适用于大部分场景。

2. C++右值引用

前面提到,其实 C++98/03 标准中就有引用,使用 “&” 表示。但此种引用方式有一个缺陷,即正常情况下只能操作 C++ 中的左值,无法对右值添加引用。举个例子:

int num = 10;
int &b = num; //正确
int &c = 10; //错误

如上所示,编译器允许我们为 num 左值建立一个引用,但不可以为 10 这个右值建立引用。因此,C++98/03 标准中的引用又称为左值引用。

注意,虽然 C++98/03 标准不支持为右值建立非常量左值引用,但允许使用常量左值引用操作右值。也就是说,常量左值引用既可以操作左值,也可以操作右值,例如:

int num = 10;
const int &b = num;
const int &c = 10;

我们知道,右值往往是没有名称的,因此要使用它只能借助引用的方式。这就产生一个问题,实际开发中我们可能需要对右值进行修改(实现移动语义时就需要),显然左值引用的方式是行不通的。为此,C++11 标准新引入了另一种引用方式,称为右值引用,用 “&&” 表示。

需要注意的,和声明左值引用一样,右值引用也必须立即进行初始化操作,且只能使用右值进行初始化,例如:

int num = 10;
//int && a = num;  // 右值引用不能初始化为左值
int && a = 10;

和常量左值引用不同的是,右值引用还可以对右值进行修改。例如:

int && a = 10;
a = 100;
cout << a << endl;	// a = 100

另外值得一提的是,C++ 语法上是支持定义常量右值引用的,例如:

const int&& a = 10; // 编译器不会报错

但这种定义出来的右值引用并无实际用处。一方面,右值引用主要用于移动语义和完美转发,其中前者需要有修改右值的权限;其次,常量右值引用的作用就是引用一个不可修改的右值,这项工作完全可以交给常量左值引用完成。

下图给出 C++ 左值引用和右值引用的可以引用的值类型和使用场景:

在这里插入图片描述

表中,Y 表示支持,N 表示不支持。

其实,C++11 标准中对右值做了更细致的划分,分别称为纯右值(Pure value,简称 pvalue)和将亡值(eXpiring value,简称 xvalue )。其中纯右值就是 C++98/03 标准中的右值,而将亡值则指的是和右值引用相关的表达式(比如某函数返回的 T && 类型的表达式)。当然对于纯右值和将亡值,都属于右值。

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

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

相关文章

【springboot+云计算】B/S医院信息管理系统源码(云HIS)

一、基于云计算技术的B/S架构的医院管理系统(简称云HIS) 采用前后端分离架构&#xff0c;前端由Angular框架、JavaScript语言开发&#xff1b;后端使用Java语言开发。系统遵循服务化、模块化原则开发&#xff0c;具有强大的可扩展性&#xff0c;二次开发方便快捷。为医疗机构提…

2023最新ChatGPT商业运营网站源码+支持ChatGPT4.0+新增GPT联网功能+支持ai绘画+实时语音识别输入+用户会员套餐+免费更新版本

2023最新ChatGPT商业运营网站源码支持ChatGPT4.0新增GPT联网功能支持ai绘画实时语音识别输入用户会员套餐免费更新版本 一、AI创作系统二、系统程序下载三、系统介绍四、安装教程五、主要功能展示六、更新日志 一、AI创作系统 提问&#xff1a;程序已经支持GPT3.5、GPT4.0接口…

Python之全-新-深-细详解

文章目录 第一章 Python环境搭建1.1. 计算机基础1.1.1. 什么是编程1.1.2. 什么是进制1.1.2.1. 进制的简介1.1.2.2. 进制的分类1.1.2.3. 进制的表示1.1.2.4. 进制的转换1.1.2.5. 原反补(了解)数据的转换负数的表示补码的引入 1.2. Python的介绍1.3. Python的安装与使用1.3.1. Py…

SSM简单项目遇到的几个问题

这几个问题&#xff0c;干扰了我很长时间。 主要因为书本的例子&#xff0c;是通过controller层返回到jsp层。但是&#xff0c;最后一个SSM项目&#xff0c;它用的是controller返回信息给Service层&#xff0c;再由Service层返回Jsp层。 实训&#xff1a;编写一个模糊查询姓名…

前端(三)——MVC与MVVM模式的battle

&#x1f604;博主&#xff1a;小猫娃来啦 &#x1f604;文章核心&#xff1a;mvc模式mvvm模式的battle 文章目录 mvc模式是什么mvc模式的优缺点优化mvc模式致命的缺点mvvm是什么&#xff0c;和mvc有什么关系&#xff1f;细看mvvm和mvc的不同 mvvm的缺点简化视图层开发 mvc模式…

E类逆变器Ltspice仿真

1 参数计算&#xff08;待续&#xff09; &#xff08;1&#xff09;确定振荡频率&#xff1a; &#xff08;2&#xff09;计算各器件参数&#xff1b; 2 电路仿真 &#xff08;1&#xff09;电路图 &#xff08;2&#xff09;电路分析 3 结果 &#xff08;1&#xff09;…

vue项目业务实现,视频监控-文件流,大屏适配方案(v-scale-screen),websocket前端

最近把以前的业务场景及解决方案整理了一下&#xff0c;具体实现的工具如下&#xff1a; 监控-视频文件流>video.js videojs-contrib-hls 大屏适配方案> v-scale-screen websocket>sockjs-client webstomp-client 视频监控-文件流 使用方法 下载video插件&#xf…

数字IC基础:状态化简与等价状态

相关阅读 数字IC基础知识&#xff1a;著名EDA公司与工具介绍 如果时序机的两个状态对于所有可能的输入序列都具有相同的输出序列&#xff08;和相同的下一状态&#xff09;&#xff0c;则称这两个状态是等价的。时序机的等价状态无法通过观察输出序列的异同对其加以区分&#…

【Web3】认识以太坊钱包

目录 区块链钱包概念 密码 私钥 Private Key 公钥Public Key Keystore 助记词 Mnemonic 如何解锁账户 区块链钱包概念 钱包用来存钱的&#xff0c;在区块链中&#xff0c;我们的数字资产都会对应到一个账户地址上&#xff0c; 只有拥 有账户的钥匙&#xff08;私钥&…

【网络进阶】Posix API与网络协议栈(五)

文章目录 1. ARP协议1.1 ARP协议的定义1.2 ARP协议的工作过程1.3 ARP协议的数据结构1.4 ARP欺骗1.5 ARP协议的局限性1.6 ARP协议与Posix API的关系 2. ARP协议例子3. ICMP协议3.1 ICMP协议的定义3.2 ICMP协议的类型3.3 ICMP协议的工作原理3.4 ICMP协议的应用3.5 ICMP协议的局限…

软考:中级软件设计师:操作系统,进程管理,前趋图,进程同步互斥,PV操作,

软考&#xff1a;中级软件设计师:操作系统 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &…

Openlayers实战:地图上显示经纬度坐标

Openlayers地图中,鼠标移动,其位置的经纬度坐会经常显示在页面中。 在我们的实战课程里,详细讲一下其做法,成为一个主力的应用。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此源代码版权归大剑师兰特所有,可供学习或商业项目…

vue中如何引入插件并使用

Vue中的插件类型 vue中有大致有三种类型的插件&#xff0c;第三方插件、基于vue开发的插件及基于vue开发的组件 第三方插件 如&#xff1a;jquery、moment.js、aixos、Highcharts等 注意&#xff1a;Highcharts也有基于vue开发的插件版本&#xff0c;具体使用方法参见下文 …

C++中的类

1、类和对象 C中通过class定义类 class A {int a; }; // 定义一个A类型的类通过类来定义对象 A a; // 定义一个A类型的对象类是一张蓝图&#xff0c;是抽象的。而对象是根据蓝图真正建造出来的建筑&#xff0c;是具象的。 对象是类的实体化 2、类的限制修饰符 类有三种修…

xmrig病毒删除

删除病毒 [rootnode101 .mint-xmr]# top | headPID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 15870 root 20 0 4597844 2.0g 4 S 1017 3.3 52:05.95 xmrig[rootnode101 .mint-xmr]# ll /proc/15870/exe lrwxrwxrwx. 1 root ro…

【C#】SqlBulkCopy批量添加注意DataTable必须与表列顺序一致,否则报错,以及关闭自增列

前篇文章在测试一个批量添加的操作&#xff0c;发现一致添加不成功&#xff0c;最后分析是字段列顺序不一致的问题 目录 1、列名不一致1.1、错误信息1.2、解决方法 2、关闭自增列2.1、不包含列2.2、特性关闭 1、列名不一致 1.1、错误信息 在调试时&#xff0c;一致提示如下错…

基于 Flink SQL CDC的实时数据同步方案

基于 Flink SQL CDC的实时数据同步方案http://www.dreamwu.com/post-1594.html

iframe编码为utf-8.嵌入页面为gb2312 ,word导出默认为gb2312 格式

使用记事本打开html&#xff0c;另存为&#xff0c;保存类型选择&#xff1a;"所有文件"、编码选择&#xff1a;“UTF-8”打开保存后文件编码类型改成utf-8 第一个步骤是为了把内容改成utf-8&#xff0c;然后直接执行第二步改编码可能会报乱码

解决printJS打印问题汇总

目录 一、打印预览表格列不全&#xff08;Element的el-table组件&#xff09; 1、打印设置“打印缩放” 2、修改el——table的底层代码&#xff08;如果页面上有多个表格慎用&#xff09; 一、打印预览表格列不全&#xff08;Element的el-table组件&#xff09; 问题描述&a…

简单的手机记事本app怎么查看提醒列表?

很多人平时都有随手记事的习惯&#xff0c;在记录事情的时候使用手机上的记事本app是一个不错的选择。有的记事本功能比较完善&#xff0c;不但能记事还能设置提醒&#xff0c;当有多条提醒内容存在时&#xff0c;简单的手机记事本app怎么查看提醒列表呢&#xff1f;以iPhone手…