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

C++完美转发(适合小白)

        我们知道,C++中有左值引用和右值引用,首先我们要知道什么是左值什么是右值。

        左值:表达式结束后依然存在的持久对象。左值可以出现在赋值语句的左边或右边。例如,变量和函数返回的引用都是左值。左值通常有持久的地址,可以被取地址操作符 & 获取地址。

        右值:通常是临时的,不能有多个引用,它们不指向持久存储。右值可以出现在赋值语句的右边,但不能出现在左边。字面量(如 42 或 "hello")和将亡值(函数返回的非引用类型)都是右值。右值通常用于描述临时对象或字面值,它们在使用后很快就会被销毁。

        那么,在将左值引用和右值引用传入函数的时候,我们有时候需要保存它的左值属性或者右值属性,这时就需要分别写出左值引用和右值引用函数重载。我们也可能需要将不同类型的参数传入函数,这时候就需要用到函数模板。

函数重载如下:

void func(int &n){cout << "左值=" << n << endl;
}void func(int &&m){cout << "右值=" << m << endl;
}

函数模板如下:

//第一种函数模板
template<class T>
void func(T &n){cout << "左值=" << n << endl;
}
template<class T>
void func(T &&m){cout << "右值=" << m << endl;
}//第二种函数模板
void func(int &n){cout << "左值=" << n << endl;
}
void func(int &&m){cout << "右值=" << m << endl;
}
void func(double &n){cout << "左值double=" << n << endl;
}
void func(double &&m){cout << "右值double=" << m << endl;
}template<class T>
void revoke(T &&t){func(t);
}

        第一种能正确输出左右值,但是,它并不能对不同类型的参数调用不同操作(不符合多态),假如你想要int类型的参数打印int,想要double类型的参数打印double,第一种函数无法实现。

        第二种不能正确输出左右值,全部都走到左值,因为t是一个左值变量,只会被转发到左值函数中。

        综上,只有用完美转发才能实现既识别左右值,又能对不同类型的参数调用不同操作。

通过forward<>()实现完美转发

void func(int &n){cout << "左值int=" << n << endl;
}
void func(int &&m){cout << "右值int=" << m << endl;
}
void func(double &n){cout << "左值double=" << n << endl;
}
void func(double &&m){cout << "右值double=" << m << endl;
}template<class T>
void revoke(T &&t){func(forward<T>(t));
}int main(){int i = 10;int &n = i;int &&m = 100;m = 10;//只能识别左右值,不能根据参数类型选择不同操作// func(n);// func(static_cast<int&&>(m));//正确推导revoke(static_cast<int&>(n));revoke(static_cast<int&&>(m));revoke(n);revoke(move(m));    //移动语义,将m的内容移动给一个临时变量,此时传递的是将亡值,会被识别成右值。move之后m的资源被转移,不应该再次使用mdouble d = 1.1;double &dn = d;double &&dm = 10.10;revoke(static_cast<double&>(dn));revoke(static_cast<double&&>(dm));// //err -- 全部是左值// revoke(n);// revoke(m);// //err -- 全部是右值// revoke(static_cast<int>(n));// revoke(static_cast<int>(m));return 0;
}

输出如下:

走到这里,又引出三个问题。1.T&&是什么        2.forward原理        3.为什么要强转

1.T&&是什么:

        有个东西叫引用折叠

                引用折叠的规则:

                        如果两个引用中至少有一个是左值引用(&),那么结果是左值引用(&

                        如果两个引用都是右值引用(&&),那么结果是右值引用(&&

                比如我们int & &&,那么它会引用折叠变成int & 

                               int && &&,会变成int &&

        引用折叠和模板很像,模板识别参数类型,引用折叠识别引用类型。比如我们template<class T>,那么输入int就会识别成int,输入double就会识别成double。在引用折叠下,输入什么值引用就会识别成什么值引用。

2.forward原理

        forward用于保持原参数的类型,比如我是int&就保持int&,在第二种函数模板中,我们已经说过了,如果不保持原参数的类型,那么t就是一个左值变量,会全部走到左值

3.为什么要强转

        查看完美转发的代码,可以发现有两个错误示例

    //err -- 全部是左值revoke(n);revoke(m);//err -- 全部是右值revoke(static_cast<int>(n));revoke(static_cast<int>(m));

        第一个 -- 在函数调用时,如果你直接传递一个具名变量(无论它是通过左值引用还是右值引用声明的),该变量作为参数传递给函数时总是作为左值传递的。如果我们不强转,那么会被识别左值,这里的强转实际上是告诉函数,我想要传递的类型是什么

        第二个 -- 当一个A类型变量强转为B类型时,实际上是创建了一个B类型的匿名对象来接收一个A类型的变量的值,而匿名对象是右值(将亡值),并且它不具名,所以会被识别成右值(只有具名变量才会默认作为左值传递)

        

相关文章:

C++完美转发(适合小白)

我们知道&#xff0c;C中有左值引用和右值引用&#xff0c;首先我们要知道什么是左值什么是右值。 左值&#xff1a;表达式结束后依然存在的持久对象。左值可以出现在赋值语句的左边或右边。例如&#xff0c;变量和函数返回的引用都是左值。左值通常有持久的地址&#xff0c;可…...

如何创建自己的 Spring Boot Starter 并为其编写单元测试

当我们想要封装一些自定义功能给别人使用的时候&#xff0c;创建Spring Boot Starter的形式是最好的实现方式。如果您还不会构建自己的Spring Boot Starter的话&#xff0c;本文将带你一起创建一个自己的Spring Boot Starter。 快速入门 创建一个新的 Maven 项目。第三方封装的…...

C++ :STL中deque的原理

deque的结构类似于哈希表&#xff0c;使用一个指针数组存储固定大小的数组首地址&#xff0c;当数据分布不均匀时将指针数组内的数据进行偏移&#xff0c;桶不够用的时候会像vector一样扩容然后将之前数组中存储的指针拷贝过来&#xff0c;从原理可以看出deque的性能是非常高的…...

AttributeError: ‘Namespace‘ object has no attribute ‘EarlyStopping‘

报错原因 这个报错信息表明在Python脚本train.py中尝试访问命令行参数args.EarlyStopping时出错&#xff0c;具体错误是AttributeError: Namespace对象没有名为EarlyStopping的属性。 在Python的argparse模块中&#xff0c;当我们通过命令行传递参数并解析时&#xff0c;解析…...

深度学习pytorch——卷积神经网络(持续更新)

计算机如何解析图片&#xff1f; 在计算机的眼中&#xff0c;一张灰度图片&#xff0c;就是许多个数字组成的二维矩阵&#xff0c;每个数字就是此点的像素值&#xff08;图-1&#xff09;。在存储时&#xff0c;像素值通常位于[0, 255]区间&#xff0c;在深度学习中&#xff0…...

【edge浏览器无法登录某些网站,以及迅雷插件无法生效的解决办法】

edge浏览器无法登录某些网站&#xff0c;以及迅雷插件无法生效的解决办法 edge浏览器无法登录某些网站&#xff0c;但chrome浏览器可以登录浏览器插件无法使用&#xff0c;比如迅雷如果重装插件重装浏览器重装迅雷后仍然出现问题 edge浏览器无法登录某些网站&#xff0c;但chro…...

OpenHarmony无人机MAVSDK开源库适配方案分享

MAVSDK 是 PX4 开源团队贡献的基于 MavLink 通信协议的用于无人机应用开发的 SDK&#xff0c;支持多种语言如 C/C、python、Java 等。通常用于无人机间、地面站与通信设备的消息传输。 MAVLink 是一种非常轻量级的消息传递协议&#xff0c;用于与无人机&#xff08;以及机载无…...

模型训练----parser.add_argument添加配置参数

现在需要配置参数来达到修改训练的方式&#xff0c;我现在需要新建一个参数来开关wandb的使用。 首先就是在def parse_option():函数里添加上你要使用的变量名 parser.add_argument("--open_wandb",type bool,defaultFalse,helpopen wandb) 到config文件里增加你的…...

数字未来:探索 Web3 的革命性潜力

在当今数字化的时代&#xff0c;Web3作为互联网的新兴范式正逐渐崭露头角&#xff0c;引发了广泛的关注和探讨。本文将深入探索数字未来中Web3所蕴含的革命性潜力&#xff0c;探讨其对社会、经济和技术的深远影响。 1. Web3&#xff1a;数字世界的下一个阶段 Web3是一个正在崛…...

群晖NAS使用Docker部署大语言模型Llama 2结合内网穿透实现公网访问本地GPT聊天服务

文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛&#xff0c;包括聊天机…...

[选型必备基础信息] 存储器

存储芯片根据断电后是否保留存储的信息可分为易失性存储芯片&#xff08;RAM&#xff09;和非易失性存储芯片&#xff08;ROM&#xff09;。 简单说&#xff0c;存储类IC分为 ROM和RAM ROM&#xff1a;EEPROM / Flash / eMMC RAM&#xff1a;SRAM/SDRAM/DDR2/DDR3/DDR4/DDR5…...

C++——C++11线程库

目录 一&#xff0c;线程库简介 二&#xff0c;线程库简单使用 2.1 传函数指针 ​编辑 2.2 传lamdba表达式 2.3 简单综合运用 2.4 线程函数参数 三&#xff0c;线程安全问题 3.1 为什么会有这个问题&#xff1f; 3.2 锁 3.2.1 互斥锁 3.2.2 递归锁 3.3 原子操作 3…...

机器学习 | 线性判别分析(Linear Discriminant Analysis)

1 机器学习中的建模 1.1 描述性建模 以方便的形式给出数据的主要特征&#xff0c;实质上是对数据的概括&#xff0c;以便在大量的或有噪声的数据中仍能观察到重要特征。重在认识数据的主要概貌&#xff0c;理解数据的重要特征。 Task&#xff1a;聚类分析&#xff0c;数据降…...

TypeScript-数组、函数类型

1.数组类型 1.1类型 方括号 let arry:number[][5,2,0,1,3,1,4] 1.2 数组泛型 let arry2:Array<number>[5,2,0,1,3,1,4] 1.3接口类型 interface makeArryRule{[index:number]:number }let arry3:makeArryRule[5,2,0,1,3,1,4] 1.4伪数组 说明&#xff1a; argument…...

Python深度学习034:cuda的环境如何配置

文章目录 1.安装nvidia cuda驱动CMD中看一下cuda版本:下载并安装cuda驱动2.创建虚拟环境并安装pytorch的torch_cuda3.测试附录1.安装nvidia cuda驱动 CMD中看一下cuda版本: 注意: 红框的cuda版本,是你的显卡能装的最高的cuda版本,所以可以选择低于它的版本。比如我的是11…...

【论文笔记】Text2QR

论文&#xff1a;Text2QR: Harmonizing Aesthetic Customization and Scanning Robustness for Text-Guided QR Code Generation Abstract 二维码通常包含很多信息但看起来并不美观。stable diffusion的出现让平衡扫描鲁棒性和美观变为可能。 为了保证美观二维码的稳定生成&a…...

【ReadPapers】A Survey of Large Language Models

LLM-Survey的llm能力和评估部分内容学习笔记——思维导图 思维导图 参考资料 A Survey of Large Language Models论文的github仓库...

站群CMS系统

站群CMS系统是一种用于批量建立和管理网站的内容管理系统&#xff0c;它能够帮助用户快速创建大量的网站&#xff0c;并实现对这些网站的集中管理。以下是三个在使用广泛的站群CMS系统&#xff0c;它们各具特色&#xff0c;可以满足不同用户的需求。 1. Z-BlogPHP Z-BlogPHP是…...

landsat8数据产品说明

1、下载数据用户手册 手册下载网址&#xff0c;搜索landsat science关键词&#xff0c;并点击到官网下载。 2、用户手册目录 3、landsat8数据产品说明 具体说明在手册的第四章&#xff0c;4.1.4数据产品章节&#xff0c;具体描述如下&#xff1a; 英文意思&#xff1a; L8 的…...

Golang 内存管理和垃圾回收底层原理(二)

一、这篇文章我们来聊聊Golang内存管理和垃圾回收&#xff0c;主要注重基本底层原理讲解&#xff0c;进一步实战待后续文章 垃圾回收&#xff0c;无论是Java 还是 Golang&#xff0c;基本的逻辑都是基于 标记-清理 的&#xff0c; 标记是指标记可能需要回收的对象&#xff0c…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...