右值引用——C++11新特性(一)
目录
一、右值引用与移动语义
1.左值引用与右值引用
2.移动构造和移动赋值
二、引用折叠
三、完美转发
一、右值引用与移动语义
1.左值引用与右值引用
- 左值:可以取到地址的值,比如一些变量名,指针等。
- 右值:不能取到地址的值,比如常量、临时对象、匿名对象、表达式结果等。
- 左值引用:给左值取别名。&表示左值引用。
- 右值引用:给右值取别名。&&表示右值引用。
- 一般情况下左值引用(&)不能引用右值,除非使用const修饰该左值引用。
- 一般情况下右值引用(&&)不能引用左值,除非用move修饰该左值。
注意:左值引用和右值引用是左值。
示例如下:
int main()
{int a = 8;//其中a为左值。int& pa=a;//pa为左值引用,引用了左值a//8;//8是一个常量为右值int(9);//9是匿名对象为右值5 + 3;//表达式的结果7为右值int&& pb = 8;//pb为右值引用,引用了右值8。int&& pc = int(9);int&& pd = 5 + 3;//const int& pl= 8;//const修饰后的左值引用可引用右值。int&& pr = move(a);//move修饰左值后可被右值引用引用。return 0;
}
2.移动构造和移动赋值
左值引用可以使得在函数传参过程中减少拷贝,在函数内直接对实参进行修改等等。这些可以大大的提高程序的执行效率。但是对于在被调函数内创建的临时对象不能直接传引用返回到原函数。因为在函数结束后这些临时对象会随着函数栈帧的销毁而销毁,而引用最底层用的是指针。所以必须得返回对象从而进行拷贝转移资源。这样的话会大大的降低程序的执行效率。
对于以上左值引用的不足之处,右值引用就可以得到一个还好的解决。
右值引用在引用右值的时候实际上是把该右值的资源的地址保存。而该资源不会被立即释放掉,相当于延长了生命周期,因为右值都是一些临时对象、常量、匿名对象等这些“将亡”值。反正这些资源又没有人使用,那么就不急着释放它可以让右值引用接管它。
而对于把左值move后进行右值引用,相当于“掠夺”资源,这种情况一般都是该左值不再被需要了,从而把它move让右值引用接管,那么原来的那个左值的状态是未定义的,要避免使用它。
当然单上面的内容,还体现不出右值引用的高效之处,接下来我们来看右值引用的两个应用的地方,移动构造和移动赋值。
移动构造和移动赋值的实现是非常简单的就是交换资源,把自己的空资源给别人把别人的拿过来。如下一个string类的移动构造和移动赋值的简单实现:
string(string&& s) {swap(s); } string& operator=(string&& s) {swap(s);return *this; }
移动构造和移动赋值相比拷贝构造和拷贝赋值效率是非常之高的,值得我们学习并使用。
二、引用折叠
C++中不能直接定义引⽤的引⽤如 int& && r = i; ,这样写会直接报错,通过模板或typedef
中的类型操作可以构成引⽤的引⽤。
通过模板或typedef中的类型操作可以构成引⽤的引⽤时,这时C++11给出了⼀个引⽤折叠的规则:右值引⽤的右值引⽤折叠成右值引⽤,所有其他组合均折叠成左值引⽤。
如下:
template<class T>
void func1(T&& x);
template<class T>
void func2(T& x);
对于func1当传入左值时是(折叠成)左值引用,当传入右值时是(折叠成)右值引用。
对于func2当传入左值时是(折叠成)左值引用,当传入右值时还是(折叠成)左值引用。
func1这样的函数模板我们通常把它称为“万能引用”。
三、完美转发
当左值与右值在函数之间一直往下传的时候。我们会无法识别它原本是左值还是右值,因为左值引用和右值引用传入下一层后都被视为左值了。会导致移动构造和移动赋值等操作失效。而完美转发就可以解决这个问题。
完美转发需要用到库提供的一个函数模板forward,源码如下:
template <class _Ty>
_Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
{ // forward an lvalue as either an lvalue or an rvaluereturn static_cast<_Ty&&>(_Arg);
}
完美转发forward它主要还是通过引⽤折叠的⽅式实现,下⾯⽰例中如果传递给func1的实参是右值,T被推导为int,没有折叠,forward内部_Arg被强转为右值引⽤返回;如果传递给func1的实参是左值,T被推导为int&,引⽤折叠为左值引⽤,forward内部_Arg被强转为左值引⽤
返回
void func1(T&& x)
{//......func2(std::forward<T>(x));
}
void func2(T&& x)
{//......
}
相关文章:
右值引用——C++11新特性(一)
目录 一、右值引用与移动语义 1.左值引用与右值引用 2.移动构造和移动赋值 二、引用折叠 三、完美转发 一、右值引用与移动语义 1.左值引用与右值引用 左值:可以取到地址的值,比如一些变量名,指针等。右值:不能取到地址的值…...
JavaScript 观察者设计模式
观察者模式:观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。而js中最常见的观察者模式就是事件触发机制。 ES5/ES6实现观察者模式(自定义事件) - 简书 先搭架子 要有一个对象ÿ…...
鸿蒙进阶篇-网格布局 Grid/GridItem(二)
hello大家好,这里是鸿蒙开天组,今天让我们来继续学习鸿蒙进阶篇-网格布局 Grid/GridItem,上一篇博文我们已经学习了固定行列、合并行列和设置滚动,这一篇我们将继续学习Grid的用法,实现翻页滚动、自定义滚动条样式&…...
数据仓库之 Atlas 血缘分析:揭示数据流奥秘
Atlas血缘分析在数据仓库中的实战案例 在数据仓库领域,数据血缘分析是一个重要的环节。血缘分析通过确定数据源之间的关系,以及数据在处理过程中的变化,帮助我们更好地理解数据生成的过程,提高数据的可靠性和准确性。在这篇文章中…...
AndroidStudio-滚动视图ScrollView
滚动视图 滚动视图有两种: 1.ScrollView,它是垂直方向的滚动视图;垂直方向滚动时,layout_width属性值设置为match_parent,layout_height属性值设置为wrap_content。 例如: (1)XML文件中: <?xml ve…...
嵌入式硬件实战基础篇(一)-STM32+DAC0832 可调信号发生器-产生方波-三角波-正弦波
引言:本内容主要用作于学习巩固嵌入式硬件内容知识,用于想提升下述能力,针对学习STM32与DAC0832产生波形以及波形转换,对于硬件的降压和对于前面硬件篇的实际运用,针对仿真的使用,具体如下: 设…...
ElasticSearch的Python Client测试
一、Python环境准备 1、下载Python安装包并安装 https://www.python.org/ftp/python/3.13.0/python-3.13.0-amd64.exe 2、安装 SDK 参考ES官方文档: https://www.elastic.co/guide/en/elasticsearch/client/index.html python -m pip install elasticsearch一、Client 代…...
【eNSP】企业网络架构链路聚合、数据抓包、远程连接访问实验(二)
一、实验目的 网络分段与VLAN划分: 通过实验了解如何将一个大网络划分为多个小的子网(VLAN),以提高网络性能和安全性。 VLAN间路由: 学习如何配置VLAN间的路由,使不同VLAN之间能够通信。 网络设备配置&am…...
独立站 API 接口的性能优化策略
一、缓存策略* 数据缓存机制 内存缓存:利用内存缓存系统(如 Redis 或 Memcached)来存储频繁访问的数据。例如,对于商品信息 API,如果某些热门商品的详情(如价格、库存、基本描述等)被大量请求…...
不一样的CSS(一)
目录 前言: 一、规则图形 1.介绍: 2.正方形与长方形(实心与空心) 2.1正方形: 2.2长方形 3.圆形与椭圆形(空心与实心) 3.1圆形与椭圆形 4.不同方向的三角形 4.1原理 4.2边框属性 5.四…...
题目:Wangzyy的卡牌游戏
登录 - XYOJ 思路: 使用动态规划,设dp[n]表示当前数字之和模三等于0的组合数。 状态转移方程:因为是模三,所以和的可能就只有0、1、2。等号右边的f和dp都表示当前一轮模三等于k的组合数。以第一行为例:等号右边表示 j转…...
国外云服务器高防多少钱一年?
国外云服务器高防多少钱一年?入门级高防云主机:这类主机通常具有较低的防御峰值,如30G或60G,价格相对较低。例如,30G峰值防御的高防云主机年费可能在2490元左右,而60G峰值防御的则可能在5044元左右。中等防…...
架构篇(04理解架构的演进)
目录 学习前言 一、架构演进 1. 初始阶段的网站架构 2. 应用服务和数据服务分离 3. 使用缓存改善网站性能 4. 使用应用服务器集群改善网站的并发处理能力 5. 数据库读写分离 6. 使用反向代理和CDN加上网站相应 7. 使用分布式文件系统和分布式数据库系统 8. 使用NoSQL和…...
【363】基于springboot的高校竞赛管理系统
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大,容错率低&am…...
Spring Boot 监视器
一、Spring Boot 监视器概述 (一)什么是 Spring Boot 监视器 定义与作用 Spring Boot 监视器(Spring Boot Actuator)是一个用于监控和管理 Spring Boot 应用程序的工具集。它提供了一系列的端点,可以获取应用程序的运…...
Javascript如何获取指定网页中的内容?
这两天有一个需求,就是通过JS去获取网页的内容,当然,除了今天我要分享的这个方法以外,其实通过Ajax的Get方法也是可以实现这个功能的,但是Ajax就比较麻烦一些了,如果只是单纯的想要获取一下纯内容ÿ…...
第2章2.3立项【硬件产品立项的核心内容】
硬件产品立项的核心内容 2.3 硬件产品立项的核心内容2.3.1 第一步:市场趋势判断2.3.2 第二步:竞争对手分析1.竞争对手识别2.根据竞争对手分析制定策略 2.3.3 第三步:客户分析2.3.4 第四步:产品定义2.3.5 第五步:开发执…...
区块链:Raft协议
Raft 协议是一种分布式共识机制,这种机制适用于网络中存在一定数量的故障节点,但不考虑“恶意”节点的情况,所以更适合作为私有链和联盟链的共识算法。 在此协议中,每个节点有三种状态: 候选者 ,可以被选…...
【C语言】位运算
我们在上学计算机的第一节课,就应该见过这些常见的运算符。然而,你可能有印象,但记不住众多操作符当中的位运算符,以及它们的作用和使用场景,我们的大脑会选择性地遗忘它认为没用的信息,存储下那些“有实际…...
计算机体系结构之多级缓存、缓存miss及缓存hit(二)
前面章节《计算机体系结构之缓存机制原理及其应用(一)》讲了关于缓存机制的原理及其应用,其中提出了多级缓存、缓存miss以及缓存hit的疑问。故,本章将进行展开讲解, 多级缓存、缓存miss以及缓存hit存在的意义是为了保持…...
【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线
【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线 主要介绍了 R78/G15 开发板基于 Arduino IDE 环境串口打印温湿度传感器 DHT11 和温度传感器 DS18B20 传感器的数据,并通过LabVIEW上位机绘制演…...
Oracle Fetch子句
FETCH 子句在 Oracle 中可以用来限制查询返回的行数 Oracle FETCH 子句语法 以下说明了行限制子句的语法: [ OFFSET offset ROWS]FETCH NEXT [ row_count | percent PERCENT ] ROWS [ ONLY | WITH TIES ]OFFSET 子句 OFFSET 子句指定在行限制开始之前要跳过行…...
Linux应用——线程池
1. 线程池要求 我们创建线程池的目的本质上是用空间换取时间,而我们选择于 C 的类内包装原生线程库的形式来创建,其具体实行逻辑如图 可以看到,整个线程池其实就是一个大型的 CP 模型,接下来我们来完成它 2. 整体模板 #pragma …...
95.【C语言】数据结构之双向链表的头插,头删,查找,中间插入,中间删除和销毁函数
目录 1.双向链表的头插 方法一 方法二 2.双向链表的头删 3.双向链表的销毁 4.双向链表的某个节点的数据查找 5.双向链表的中间插入 5.双向链表的中间删除 6.对比顺序表和链表 承接94.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删文章 1.双向链表的头插 方法…...
leetcode82:删除排序链表中的重复节点||
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。 示例 1: 输入:head [1,2,3,3,4,4,5] 输出:[1,2,5]示例 2: 输入:head [1,1,1,2…...
【C#】使用.net9在C#中向现有对象动态添加属性
在 C# 中向现有对象动态添加属性并不像在 Python 或 JavaScript 中那样容易,因为 C# 是一种强类型语言。 但是,我们可以通过使用一些技术和库来实现这一点,例如扩展方法、字典等。本文将详细介绍如何在 C# 中实现这一点。ExpandoObject 方法 …...
Linux进程信号(信号的产生)
目录 什么是信号? 信号的产生 信号产生方式1:键盘 前台进程 后台进程 查看信号 signal系统调用 案例 理解进程记录信号 软件层面 硬件层面 信号产生方式2:指令 信号产生方式3:系统调用 kill系统调用 案例 其他产生信号的函数调用 1.rais…...
97_api_intro_imagerecognition_pdf2word
通用 PDF OCR 到 Word API 数据接口 文件处理,OCR,PDF 高可用图像识别引擎,基于机器学习,超精准识别率。 1. 产品功能 通用识别接口;支持中英文等多语言字符混合识别;formdata 格式 PDF 文件流传参…...
【算法】【优选算法】二分查找算法(上)
目录 一、二分查找简介1.1 朴素二分模板1.2 查找区间左端点模版1.3 查找区间右端点模版 二、leetcode 704.⼆分查找2.1 二分查找2.2 暴力枚举 三、Leetcode 34.在排序数组中查找元素的第⼀个和最后⼀个位置3.1 二分查找3.2 暴力枚举 四、35.搜索插⼊位置4.1 二分查找4.2 暴力枚…...
springboot初体验
目录 环境 controller 修改端口号 更改banner图标 运行结果 最核心的:自动装配 环境 jdk17springboot3.3.5maven3.8.2 controller controller层和启动类同级 package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping;…...
手机网站优化需要注意什么/腾讯nba新闻
本文为原创,如需转载,请注明作者和出处,谢谢! 指针类型是C、Pascal等语言中比较重要的数据类型。在使用上很灵活。在C中可以使用如下的语句一个int指针类型:int*p;如果要为指针变量赋值,可以使用如下的语句…...
定制营销产生的原因/湖南seo优化价格
现象:诺顿更新到5月17日的病毒库以后,会造成重起机器后无法进入系统,安全模式也无法进入,产生系统蓝屏现象。解决办法:暂时停用诺顿,等待新的升级病毒库。恢复办法:将C:\windows\system32\netap…...
武汉专业制作网站/兰州网站seo
出现如下问题, 解决方法: 更换gensim的版本 pip install gensim 3.0.0...
ajax网站模板/seo值怎么提高
类模板中重载的(): ()的重载很特殊,因为如果一个类重载了()那么该类的对象就称为函数对象。也就是这个类的对象可以作为函数被调用或者作为函数指针传入其他函数。我们在重载&#…...
网站速度慢的原因/免费推广的方式
有一段时间,我一直在思考什么是团队文化,包括几年前曾经被反复提及的工程师文化等等。 但我始终觉得文化和角色之间并没有那么强的关联关系,我觉得文化和人的性格的关联度更高一些。 如果从这个角度看的话,我觉得搞技术的大致可以…...
福州网站建站建设/网络优化是做什么的
TouchMode模式1)singleTOP栈顶单实例如果A(activity)跳转到B(activity)后,B如果调用自身就会出多重复的B,这样子用户体验差,这时候,我们可以在清单中设置加载模式,模式为栈顶单实例&…...