万能引用与完美转发

万能引用与完美转发

    • 万能引用
    • 完美转发
    • 完美转发的应用场景
    • 万能引用的一个小点

万能引用

注意:当&&出现在模板中时,不是右值引用,而是叫万能引用。比如下面的T&& t

template<typename T>
void PerfectForward(T&& t)
{Fun(t);
}

万能引用:

  • 当实参是左值,那么T&& t就是个左值引用

    有些地方,也会叫做引用折叠

    什么意思呢?就是原本形参是T&& t,但比如当实参是个int类型的变量,那么形参这里的模板参数就会变成:int& t。原本两个&&,现在变成一个&。因此形象的称为是引用折叠

  • 当实参是右值,那么T&& t就是个右值引用

为什么会有万能引用呢?归根结底是因为,这里的T是通过形参t推导出来的,假如实参是10,那么T就是int&&;假如实参是int类型的变量,那么T就是int&

完美转发

  • 问题引出

我们看如下代码:

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<typename T>
void PerfectForward(T&& t)
{Fun(t);
}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;
}

打印结果:在这里插入图片描述

为什么打印结构都是左值引用呢?第一、三、五不都传的是右值吗?

  • 原因分析

关键问题出在了这里:T&& t

右值引用会被编译器识别为左值。即这里的t是个左值

因此,在void PerfectForward(T&& t)中,实参传递到t中,不论实参是右值还是左值,t始终是个左值。然后再Fun(t);,调用的也当然都是左值引用的函数

  • 深入思考

假如我想要实参是右值t就是右值,实参是左值t就是左值呢?那么就需要用到完美转发

完美转发:在传参的过程中保留对象原生类型属性。完美转发的实现需要用到库里面的函数forward()

也就是说,右值引用会被默认识别为左值,如果想让其保持原本的属性,那么就用完美转发

对上面的例子,加上完美转发后,结果如下:

在这里插入图片描述

完美转发的应用场景

看如下例子:(右值引用中的场景二)

int main()
{list<xy::string> it;it.push_back("111");return 0;
}

C++11之前, 上述代码的调用过程:

在这里插入图片描述

C++11后, “111”是个右值,因此在红框处可以移动拷贝。所以调用过程变成了下面:

在这里插入图片描述

到这里就和我们在右值引用中所讲的过程一样。但是其实上述代码是存在问题的

这是因为:首先"111"传给push_back(T&& x)没有问题,但此时x默认是个左值,然后insert(end(),x)这一调用,并不能调用到右值引用版本的insert,后面的Node(x)也不会调用到右值引用版本的list_node构造函数。所以最终也不是移动拷贝,而是深拷贝

完美转发的出现,很好的解决了上述问题,完美只需如下修改:

在这里插入图片描述

让每个右值引用形参都保留其原本属性,这样最终就可以调用到移动拷贝

万能引用的一个小点

在完美转发的应用场景中:

list_node的构造函数会有两个版本,一个是左值引用的版本,一个是右值引用的版本:

template<class T>
struct list_node
{list_node<T>* _prev;list_node<T>* _next;T _val;list_node(const T& val):_prev(nullptr), _next(nullptr), _val(val){}list_node(T&& val): _prev(nullptr), _next(nullptr), _val(forward<T>(val)){}
};

在万能引用中说到:模板中出现&&不是右值引用,而是万能引用。那这里的list_node(T&& val)是万能引用吗?如果是的话,那么list_node(const T& val)这个左值引用的函数是不是就没有存在的必要了?

其实这里不是万能引用,list_node(const T& val)也不能删去

因为我们说的万能引用最核心的因素在于,模板参数T是可以通过形参val推出来的,而这里的T并不是通过val推导出来的,而是在这里在这里插入图片描述
就确定了的

但是我们只需如下:

template<class T>
struct list_node
{list_node<T>* _prev;list_node<T>* _next;T _val;template<class Ty>list_node(Ty&& val): _prev(nullptr), _next(nullptr), _val(forward<Ty>(val)){}
};

那么就可以使得其变成万能引用(类模板中再用函数模板)

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

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

相关文章

民宿在线预订系统

摘要 随着国家的发展&#xff0c;人们也更加重视自己的业余时间。在特定的假期或休闲时间外出度假已逐渐成为这个时代的趋势。在我国&#xff0c;随着经济的发展和城市居民物质生活水平的提高&#xff0c;旅游业也呈现出越来越受欢迎的趋势。同时随着人口的快速流动&#xff0…

代理网络基础设施 101:增强安全性、速度和可扩展性

编辑代理网络在现代网络架构中发挥着重要作用&#xff0c;充当管理和重新路由数据流的中介。它们处理的数据可以是各种类型&#xff0c;包括搜索查询和潜在的敏感客户信息&#xff0c;这凸显了它们在数据安全方面的作用。 然而&#xff0c;代理的好处不仅限于安全性。它们为用…

人工智能与生物信息组学 || 2. 非编码 RNA 与疾病关联分析 || 2.2 非编码 miRNA 与疾病关联关系预测

非编码 miRNA 与疾病关联关系预测 越来越多的研究表明&#xff0c;一个复杂疾病通常经由多个 miRNA 协同调控&#xff0c;一个 miRNA 通常参与多个疾病的发生发展过程。因此&#xff0c;预测 miRNA 与疾病的关联关系成为一个当前的研究热点。下面我们将探讨一种 miRNA 和疾病关…

技术驱动会展:展位导航系统的架构与实现

随着会展行业的快速发展&#xff0c;大型会展中心面临着如何提升参展者体验、提高招商效率的挑战。针对客户反馈的展馆面积大、展位查找困难等问题&#xff0c;维小帮提出一套智慧会展导航解决方案&#xff0c;旨在通过先进的室内导航技术提升会展中心的运营效率和参展者的满意…

小阿轩yx-MySQL数据库初体验

小阿轩yx-MySQL数据库初体验 数据库简介 21 世纪迈入了“信息爆炸时代”&#xff0c;大量的数据、信息在不断产生&#xff0c;伴随而来的就是如何安全、有效地存储、检索和管理它们。 对数据的有效存储、高效访问、方便共享和安全控制已经成为信息时代亟待解决的问题。 使用…

QThread 与QObject::moveToThread在UI中的应用

1. QThread的两种用法 第一种用法就是继承QThread&#xff0c;然后覆写 virtual void run()&#xff0c; 这种用法的缺点是不能利用信号槽机制。 第二种用法就是创建一个线程&#xff0c;创建一个对象&#xff0c;再将对象moveToThread, 这种可以充分利用信号槽机制&#xff…

canal 服务安装

简介&#xff1a;Canal 是阿里巴巴开源的一个基于 MySQL 数据库增量日志解析的中间件&#xff0c;用于提供准实时的数据同步功能。 准备工作 1.修改配置文件 ,需要先开启 Binlog 写入功能&#xff0c;配置 binlog-format 为 ROW 模式&#xff0c;my.cnf 中配置如下&#xf…

五种实用方法!手把手教你系统盘瘦身

随着电脑的使用时间变长&#xff0c;电脑硬盘会逐渐被各种类型的数据占满&#xff0c;其中系统盘的可用空间也在慢慢变小。这是因为系统在运行过程中会产生大量临时文件和缓存文件&#xff0c;同时&#xff0c;系统的每一次更新升级也都会生成相关的文件夹存放在系统盘中&#…

LeetCode题练习与总结:克隆图--133

一、题目描述 给你无向 连通 图中一个节点的引用&#xff0c;请你返回该图的 深拷贝&#xff08;克隆&#xff09;。 图中的每个节点都包含它的值 val&#xff08;int&#xff09; 和其邻居的列表&#xff08;list[Node]&#xff09;。 class Node {public int val;public L…

阐述一下Golang中defer的原理

基本用法 在Go语言中&#xff0c;defer关键字用于在函数返回前执行一段代码或调用一个清理函数。这对于处理文件关闭、解锁或者返回一些资源到资源池等操作非常有用。 其基本用法如下所示&#xff1a; package mainimport "fmt"func main() {example() }func exam…

如何使用Rekono结合多种工具自动完成渗透测试

关于Rekono Rekono是一款功能强大的自动化渗透测试工具&#xff0c;该工具能够结合其他多种网络安全工具并以自动化的形式完成整个渗透测试过程。在工具运行的过程中所收集到的数据将通过电子邮件或Telegram同时发送给用户&#xff0c;如果需要更加高级的漏洞管理功能&#xf…

浏览器(Browser):轻量级浏览器,高效浏览新体验

在可的哥桌面&#xff08;Codigger Desktop&#xff09;&#xff0c;我们始终秉持创新精神&#xff0c;致力于提供卓越的用户体验。如今&#xff0c;我们激动地宣布一项全新功能的发布——轻量级浏览器Browser。这款浏览器的推出&#xff0c;正是我们对用户体验追求的再次体现&…

设施布置之车间布局优化SLP分析

一 物流分析&#xff08;Flow Analysis&#xff09; 的基本方法 1、当物料移动是工艺过程的主要部分时&#xff0c;物流分析就是工厂布置设计的核心工作&#xff0c;也是物料搬运分析的开始。 2、零部件物流是该部件在工厂内移动时所走过的路线&#xff0c; 物流分析不仅要考虑…

免费ai写作?这三款软件是你的好帮手!

在信息爆炸的今天&#xff0c;自媒体已成为越来越多人展现自我、分享知识的平台。然而&#xff0c;对于许多自媒体创作者来说&#xff0c;写作过程中的灵感枯竭、文笔不畅等问题常常困扰着他们。幸运的是&#xff0c;随着人工智能技术的飞速发展&#xff0c;免费AI写作软件应运…

2024全国高校名单发布,电子版下载!

今天&#xff0c;教育部网站发布了《全国高等学校名单》。截至2024年6月20日&#xff0c;全国高等学校共计3117所&#xff0c;其中&#xff1a;普通高等学校2868所&#xff0c;含本科学校1308所、高职&#xff08;专科&#xff09;学校1560所&#xff1b;成人高等学校249所。本…

任务4.8.3 利用SparkSQL统计每日新增用户

实战概述&#xff1a;利用SparkSQL统计每日新增用户 任务背景 在大数据时代&#xff0c;快速准确地统计每日新增用户是数据分析和业务决策的重要部分。本任务旨在使用Apache SparkSQL处理用户访问历史数据&#xff0c;以统计每日新增用户数量。 任务目标 处理用户访问历史数…

简单了解雪花算法

雪花算法是什么 不多解释。看一看 具体是怎么 生产 唯一ID 的。 ID 由多个数据组合拼接成64位&#xff0c;分别是 时间戳 服务器节点ID 序列号&#xff0c;每个数据项占的位数不固定&#xff0c;可以根据实际需求设置。首位 1 个二进制位 是 符号位。 public long allocate(l…

数字样机:飞行器状态控制系统仿真

引言&#xff1a;数字样机起源于20世纪90年代&#xff0c;是一种用数字化模型代替实际物理样机进行仿真分析的技术。 传统的飞行器研发流程往往遵循一套特定的循环结构&#xff1a;在设计初期&#xff0c;工程人员需要对飞行器提供一个综合的设计思路&#xff08;初期蓝图&…

Linux【实操篇-文件目录类命令】

05【实操篇-文件目录类命令】 1.pwd 显示当前工作目录的绝对路径 pwd:print working directory 打印工作目录 到现在为止&#xff0c;我们还不知道自己在系统的什么地方。在浏览器上&#xff0c;我们能够通过导航栏上的url&#xff0c;了解到自己在互联网上的具体坐标。相似的…

Linux权限理解

目录 一.权限的概念 二.Linux权限管理 1.文件访问者的分类&#xff08;人&#xff09; 2.文件类型和访问权限&#xff08;事物属性&#xff09; 3.文件权限值的表示方法 4.文件访问权限的相关设置方法 5.修改文件的拥有者 6.修改文件所属组 7.查看或修改文件权限掩码 …