当前位置: 首页 > news >正文

右值引用——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.左值引用与右值引用 左值&#xff1a;可以取到地址的值&#xff0c;比如一些变量名&#xff0c;指针等。右值&#xff1a;不能取到地址的值…...

JavaScript 观察者设计模式

观察者模式:观察者模式&#xff08;Observer mode&#xff09;指的是函数自动观察数据对象&#xff0c;一旦对象有变化&#xff0c;函数就会自动执行。而js中最常见的观察者模式就是事件触发机制。 ES5/ES6实现观察者模式(自定义事件) - 简书 先搭架子 要有一个对象&#xff…...

鸿蒙进阶篇-网格布局 Grid/GridItem(二)

hello大家好&#xff0c;这里是鸿蒙开天组&#xff0c;今天让我们来继续学习鸿蒙进阶篇-网格布局 Grid/GridItem&#xff0c;上一篇博文我们已经学习了固定行列、合并行列和设置滚动&#xff0c;这一篇我们将继续学习Grid的用法&#xff0c;实现翻页滚动、自定义滚动条样式&…...

数据仓库之 Atlas 血缘分析:揭示数据流奥秘

Atlas血缘分析在数据仓库中的实战案例 在数据仓库领域&#xff0c;数据血缘分析是一个重要的环节。血缘分析通过确定数据源之间的关系&#xff0c;以及数据在处理过程中的变化&#xff0c;帮助我们更好地理解数据生成的过程&#xff0c;提高数据的可靠性和准确性。在这篇文章中…...

AndroidStudio-滚动视图ScrollView

滚动视图 滚动视图有两种: 1.ScrollView&#xff0c;它是垂直方向的滚动视图;垂直方向滚动时&#xff0c;layout_width属性值设置为match_parent&#xff0c;layout_height属性值设置为wrap_content。 例如&#xff1a; &#xff08;1&#xff09;XML文件中: <?xml ve…...

嵌入式硬件实战基础篇(一)-STM32+DAC0832 可调信号发生器-产生方波-三角波-正弦波

引言&#xff1a;本内容主要用作于学习巩固嵌入式硬件内容知识&#xff0c;用于想提升下述能力&#xff0c;针对学习STM32与DAC0832产生波形以及波形转换&#xff0c;对于硬件的降压和对于前面硬件篇的实际运用&#xff0c;针对仿真的使用&#xff0c;具体如下&#xff1a; 设…...

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划分&#xff1a; 通过实验了解如何将一个大网络划分为多个小的子网&#xff08;VLAN&#xff09;&#xff0c;以提高网络性能和安全性。 VLAN间路由&#xff1a; 学习如何配置VLAN间的路由&#xff0c;使不同VLAN之间能够通信。 网络设备配置&am…...

独立站 API 接口的性能优化策略

一、缓存策略* 数据缓存机制 内存缓存&#xff1a;利用内存缓存系统&#xff08;如 Redis 或 Memcached&#xff09;来存储频繁访问的数据。例如&#xff0c;对于商品信息 API&#xff0c;如果某些热门商品的详情&#xff08;如价格、库存、基本描述等&#xff09;被大量请求…...

不一样的CSS(一)

目录 前言&#xff1a; 一、规则图形 1.介绍&#xff1a; 2.正方形与长方形&#xff08;实心与空心&#xff09; 2.1正方形&#xff1a; 2.2长方形 3.圆形与椭圆形&#xff08;空心与实心&#xff09; 3.1圆形与椭圆形 4.不同方向的三角形 4.1原理 4.2边框属性 5.四…...

题目:Wangzyy的卡牌游戏

登录 - XYOJ 思路&#xff1a; 使用动态规划&#xff0c;设dp[n]表示当前数字之和模三等于0的组合数。 状态转移方程&#xff1a;因为是模三&#xff0c;所以和的可能就只有0、1、2。等号右边的f和dp都表示当前一轮模三等于k的组合数。以第一行为例&#xff1a;等号右边表示 j转…...

国外云服务器高防多少钱一年?

国外云服务器高防多少钱一年&#xff1f;入门级高防云主机&#xff1a;这类主机通常具有较低的防御峰值&#xff0c;如30G或60G&#xff0c;价格相对较低。例如&#xff0c;30G峰值防御的高防云主机年费可能在2490元左右&#xff0c;而60G峰值防御的则可能在5044元左右。中等防…...

架构篇(04理解架构的演进)

目录 学习前言 一、架构演进 1. 初始阶段的网站架构 2. 应用服务和数据服务分离 3. 使用缓存改善网站性能 4. 使用应用服务器集群改善网站的并发处理能力 5. 数据库读写分离 6. 使用反向代理和CDN加上网站相应 7. 使用分布式文件系统和分布式数据库系统 8. 使用NoSQL和…...

【363】基于springboot的高校竞赛管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…...

Spring Boot 监视器

一、Spring Boot 监视器概述 &#xff08;一&#xff09;什么是 Spring Boot 监视器 定义与作用 Spring Boot 监视器&#xff08;Spring Boot Actuator&#xff09;是一个用于监控和管理 Spring Boot 应用程序的工具集。它提供了一系列的端点&#xff0c;可以获取应用程序的运…...

Javascript如何获取指定网页中的内容?

这两天有一个需求&#xff0c;就是通过JS去获取网页的内容&#xff0c;当然&#xff0c;除了今天我要分享的这个方法以外&#xff0c;其实通过Ajax的Get方法也是可以实现这个功能的&#xff0c;但是Ajax就比较麻烦一些了&#xff0c;如果只是单纯的想要获取一下纯内容&#xff…...

第2章2.3立项【硬件产品立项的核心内容】

硬件产品立项的核心内容 2.3 硬件产品立项的核心内容2.3.1 第一步&#xff1a;市场趋势判断2.3.2 第二步&#xff1a;竞争对手分析1.竞争对手识别2.根据竞争对手分析制定策略 2.3.3 第三步&#xff1a;客户分析2.3.4 第四步&#xff1a;产品定义2.3.5 第五步&#xff1a;开发执…...

区块链:Raft协议

Raft 协议是一种分布式共识机制&#xff0c;这种机制适用于网络中存在一定数量的故障节点&#xff0c;但不考虑“恶意”节点的情况&#xff0c;所以更适合作为私有链和联盟链的共识算法。 在此协议中&#xff0c;每个节点有三种状态&#xff1a; 候选者 &#xff0c;可以被选…...

【C语言】位运算

我们在上学计算机的第一节课&#xff0c;就应该见过这些常见的运算符。然而&#xff0c;你可能有印象&#xff0c;但记不住众多操作符当中的位运算符&#xff0c;以及它们的作用和使用场景&#xff0c;我们的大脑会选择性地遗忘它认为没用的信息&#xff0c;存储下那些“有实际…...

计算机体系结构之多级缓存、缓存miss及缓存hit(二)

前面章节《计算机体系结构之缓存机制原理及其应用&#xff08;一&#xff09;》讲了关于缓存机制的原理及其应用&#xff0c;其中提出了多级缓存、缓存miss以及缓存hit的疑问。故&#xff0c;本章将进行展开讲解&#xff0c; 多级缓存、缓存miss以及缓存hit存在的意义是为了保持…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...