右值引用与移动语义与完美转发

news2024/11/23 23:42:57

右值引用

       右值

什么是右值,没有地址临时数据的我们称之为右值

 我们无法对10、a+a、字符串取地址的值我们称之为右值。因为他们是临时数据,并不保存再内存中,所以我们右值没有地址,也无法被赋值(除const外,左值都可被赋值。

注意:

左值引用与右值引用可以交叉引用使用,但是需要加些东西。

int a=10;         //允许

int& ra=a;        //允许

int&& rr=10;      //允许

int&& _rr=a       //非法

int&& _rr=move(a) //允许

int& ra=10;      //非法

const int&ra=10;  //允许

move()

将传入的数据,不论是左值还是右值都返回一个右值。

移动语义

这里才是右值的深化,为什么怎么说呢?再c++11前我们的结构体返回不能接收栈内局部定义的变量,因为在销栈的时候我们的数据会连同这栈一同销毁,所以当返回的时候需要传值返回。

to_string就是最好的例子。

 所以再C++11后我们的新增加了移动拷贝以及移动赋值。

这里我们先了解一个知识点,将亡值。

有哪些数据成为将亡值呢?

 我们的右值引用可以对这些数据做引用。

 为什么要要有移动语义呢?移动语义大大减少了对返回值的拷贝,高效的利用的将亡值数据。

 

 这样我们就对ret的资源充分的利用,而不是单纯的拷贝构造。多次的移动构造,成功的将ret对象指向数据空间转移到了receive对象。

完美转发

有一个值得注意的是,在右值应用后的数据会成为左值。假设完美vector存放的是string为元素的数组,这情况下就需要完美转发

模板中的&& 万能引用

何为万能引用,既可以引用左值也可以引用右值。

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }

template<class Ty>
void  PerfectForward(Ty&&x)
{
	Fun(x);
}

int main()
{
	PerfectForward(10);           // 右值
	int a;
	PerfectForward(a);            // 左值
	PerfectForward(std::move(a)); // 右值
	const int b = 8;
	PerfectForward(b);      // const 左值
	PerfectForward(std::move(b)); // const 右值
	return 0;
}

但是在进入PerfectForward函数后的,不论是说明值,在传入下一级函数后都属于左值数据。

 为了保持数据在传输过程中的数值类型(左右值)不发生改变,我们引入了完美转发的概念。

经过x是什么值引用,什么类型

实际作用在于,容器存储数据的时候,如果元素是自定义类型,我们可以用完美转发保持右值的属性

template<class T>
struct ListNode
{
	ListNode* _next = nullptr;
	ListNode* _prev = nullptr;
	T _data;
};
template<class T>
class List
{
	typedef ListNode<T> Node;
public:
	List()
	{
		_head = new Node;
		_head->_next = _head;
		_head->_prev = _head;
	}
	void PushBack(T&& x)
	{
		//Insert(_head, x);
		Insert(_head, std::forward<T>(x));
	}
	void PushBack(const T& x)
	{
		Insert(_head, x);
	}

	void Insert(Node* pos, T&& x)
	{
		Node* prev = pos->_prev;
		Node* newnode = new Node;
		newnode->_data = std::forward<T>(x); // 关键位置
		// prev newnode pos
		prev->_next = newnode;
		newnode->_prev = prev;
		newnode->_next = pos;
		pos->_prev = newnode;
	}
	void Insert(Node* pos, const T& x)
	{
		Node* prev = pos->_prev;
		Node* newnode = new Node;
		newnode->_data = x; // 关键位置
		// prev newnode pos
		prev->_next = newnode;
	}
	newnode->_prev = prev;
	newnode->_next = pos;
	pos->_prev = newnode;
private:
	Node* _head;
};
int main()
{
	List<zjy::string> lt;
	lt.PushBack("1111");
	lt.PushFront("2222");
	return 0;
}

 

 每一层都需要被完美转发才能抵达最后的移动构造

 

 

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

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

相关文章

【Elasticsearch】学好Elasticsearch系列-分词器

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 先看后赞&#xff0c;养成习惯。 点赞收藏&#xff0c;人生辉煌。 文章目录 规范化&#xff1a;normalization字符过滤器&#xff1a;character filterHTML Strip Character FilterMapping Character FilterP…

IMV6.0

一、背景 经历了多个版本&#xff0c;基础内容在前面&#xff0c;可以使用之前的基础环境&#xff1a; v1&#xff1a; https://blog.csdn.net/wtt234/article/details/132139454 v2&#xff1a; https://blog.csdn.net/wtt234/article/details/132144907 v3&#xff1a; https…

vue实现pdf预览功能

背景&#xff1a;材料上传之后点击预览实现在浏览器上预览的效果 效果如下&#xff1a; 实现代码如下&#xff1a; //预览和下载操作 <el-table-column fixed"right" label"操作" width"210"><template #default"scope">…

JAVA Android 正则表达式

正则表达式 正则表达式是对字符串执行模式匹配的技术。 正则表达式匹配流程 private void RegTheory() {// 正则表达式String content "1998年12月8日&#xff0c;第二代Java平台的企业版J2EE发布。1999年6月&#xff0c;Sun公司发布了第二代Java平台(简称为Java2) &qu…

每次执行@Test方法前都执行一次DB初始化(SpringBoot Test + JUnit5环境)

引言 在执行单元测试时&#xff0c;可以使用诸如H2内存数据库替代线上的Mysql数据库等&#xff0c;如此在执行单元测试时就能尽可能模拟真实环境的SQL执行&#xff0c;同时也无需依赖线上数据库&#xff0c;增加了测试用例执行环境的可移植性。而使用H2数据库时&#xff0c;通…

Node.js |(二)Node.js API:fs模块 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;文件写入&#x1f407;writeFile 异步写入&#x1f407;writeFileSync 同步写入&#x1f407;appendFile / appendFileSync 追加写入&#x1f407;createWriteStrea…

点成分享丨qPCR仪的原理与使用——以Novacyt产品为例

近年来&#xff0c;PCR检测在多种领域发挥着巨大的作用。短时高效和即时监测都成为了PCR仪发展的方向。作为世界领先的制造商之一&#xff0c;Novacyt公司为来自全球多个国家和行业的用户提供了优质的qPCR仪。 MyGo Mini S qPCR仪是一种紧凑型的实时qPCR仪&#xff0c;非常适合…

【算法|双指针系列No.1】leetcode283. 移动零

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

c++进阶--二叉搜索树

目录 前言 一、二叉搜索树 1.二叉搜索树概念 2.二叉搜索树操作 二、二叉搜索树实现 0.定义一个节点 1.定义一棵树 2.增删改查 2.1.查找 2.2.插入 2.3.删除 2.3.1非递归删除法 a.只有左孩子 -- 删除14 b.只有右孩子-- 删除10 c.有左右孩子--删除8 2.3.2递归删除…

【论文总结】Chatting with GPT-3 for Zero-Shot Human-Like Mobile Automated GUI Testing

与GPT-3对话进行零尝试人类化移动自动化GUI测试 摘要&#xff1a; 移动应用在人们的日常生活中变得不可或缺&#xff0c;而自动化图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;测试广泛用于应用程序质量保证。对于自动化GUI测试&#xff0c;越…

rv1126更新rknpu驱动教学

测试平台&#xff1a;易佰纳rv1126 38板 查看板端版本-------------------------------------------------- 1&#xff1a;查看npu驱动版本 dmesg | grep -i galcore&#xff0c;可以看到版本为6.4.3.5 2&#xff1a;查看rknn-server版本 strings /usr/bin/rknn_server | g…

新能源电动车充电桩控制主板的材料选择

新能源电动车充电桩控制主板的材料选择 你是否想过&#xff0c;汽车充电桩控制主板的材料选择竟然还有这么多讲究?不再只是简单的充电问题&#xff0c;而是涉及到耐高温、耐高压、耐腐蚀、耐潮湿、耐油污、低热耗等方方面面。 首先&#xff0c;安全性是材料选择的首要考虑因素…

mysql自增主键不连续情况分析

1.唯一键冲突 比如increnment_test中已经存在了co1为3的记录,当再插入col1为3的记录时,就会出现主键不唯一错误,但此时自增主键已经1,所以会发生主键不连续情况 DROP TABLE IF EXISTS increnment_test; CREATE TABLE increnment_test (id int(0) NOT NULL AUTO_INCREMENT,col…

svg使用技巧

什么是svg SVG 是一种基于 XML 语法的图像格式&#xff0c;全称是可缩放矢量图&#xff08;Scalable Vector Graphics&#xff09;。其他图像格式都是基于像素处理的&#xff0c;SVG 则是属于对图像的形状描述&#xff0c;所以它本质上是文本文件&#xff0c;体积较小&#xf…

Python-OpenCV中的图像处理

Python-OpenCV中的图像处理 颜色空间转换物体跟踪获取HSV的值几何变换图像缩放图像平移图像旋转仿射变换透视变换 图像阈值单阈值自适应阈值Otsus二值化 颜色空间转换 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种&#xff1…

ZMQ发布订阅模式二次封装

ZeroMQ 参考ZMQ从入门到掌握一 ZeroMQ是一种基于消息队列的多线程网络库&#xff0c;其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象&#xff0c;提供跨越多种传输协议的套接字。ZeroMQ 并不是一个对 socket 的封装&#xff0c;不能用它去实现已有的网络协议。它有…

加密、解密、编码

urlencode urlencode_百度百科 Base64是一种二进制到文本的编码方式&#xff0c;而且编码出的字符串只包含ASCII基础字符 下图是Base64码表&#xff0c;可以看到从0到63的每个数字都对应一个上面的一个字符。 文件-base64字符串互转 sun.misc包中的类 try (FileOutputStre…

Node.Js安装与配置教程

目录 1.下载官网 2.选择安装路径 3.添加环境变量 4.验证是否安装成功 5.修改模块下载位置 (1)查看npm默认存放位置 6.在node.js安装目录下&#xff0c;创建两个文件夹 7.修改默认文件夹 8.测试默认位置是否更改成功 9.安装报错解决办法 10.路径未更改成功解决办法 …

MIT 6.830数据库系统 -- lab six

MIT 6.830数据库系统 -- lab six 项目拉取引言steal/no-force策略redo log与undo log日志格式和检查点 开始回滚练习1&#xff1a;LogFile.rollback() 恢复练习2&#xff1a;LogFile.recover() 测试结果疑问点分析 项目拉取 原项目使用ant进行项目构建&#xff0c;我已经更改为…

【uniapp 小程序开发页面篇】代码编写规范 | 页面编写规范 | 小程序API

博主&#xff1a;_LJaXi Or 東方幻想郷 专栏&#xff1a; uni-app | 小程序开发 开发工具&#xff1a;HBuilderX 小程序开发页面篇 小程序组件规范小程序介绍小程序规范代码编写规范须遵循的开发规范 运行特性编译器选择编译规则工程目录结构static目录 使用注意static目录 条件…