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

C++ 11新特性之完美转发

概述

        在C++编程语言的演进过程中,C++ 11标准引入了一系列重大革新,其中之一便是“完美转发”机制。这一特性使得模板函数能够无损地传递任意类型的实参给其他函数或构造函数,从而极大地增强了C++在泛型编程和资源管理方面的灵活性与效率。

        完美转发的目标是在模板函数中保持原始参数的所有属性(比如:左值、右值、const/volatile限定等),确保无论传入的是什么类型的参数,都能够正确地传递到后续的函数调用中。这在处理具有复杂类型和引用性质的函数参数时显得尤为重要,尤其是在需要保持移动语义的情况下。

        在C++ 98/03标准下,模板参数默认为非引用类型,导致无法直接传递左值引用或者右值引用。同时,由于模板参数推导规则的限制,对于左值引用参数,即使使用typename T&也无法区分出右值引用。因此,为了实现完美转发,C++ 11引入了万能引用和std::forward函数。

万能引用和std::forward

        万能引用是指形如T&&的模板参数,在某些情况下可以接受任何类型的引用。这里的T会根据实参的实际类型进行推导,因此,它可以是左值引用也可以是右值引用。当模板参数T被绑定到一个具体的左值上时,T&&会成为一个左值引用。而当它被绑定到右值或者临时对象时,T&&则会成为右值引用。

        std::forward<T>(arg)是一个用于完美转发的关键工具,它负责维护实参原有的左值/右值引用属性,并在必要时强制转换为右值引用以便执行移动操作。

        在完美转发场景中,通常结合万能引用和std::forward来编写模板函数,以达到无损传递参数的目的。

        在下面的示例代码中,Forward模板函数接受一个参数T&& arg,这里的T&&在特定情况下被称为万能引用。在模板实例化时,编译器会根据传入的实际参数类型推断T。如果传入的是左值,则T会被推断为左值引用类型;如果传入的是右值,则T会被推断为非引用类型(即右值引用会退化成普通类型)。因此,在函数内部,arg可以是任何类型的左值引用或右值。

        Forward函数体内部调用了Process函数,并通过std::forward<T>(arg)将arg无损地传递给Process函数。std::forward的作用是保持实参原有的左值/右值性质不变,这样当arg被传递给Process时,它仍然保持着原来的引用属性。

        在main函数中,当调用Forward(nNumber)时,因为nNumber是一个左值,所以T被推断为int&类型,也就是说arg在这里是一个int&类型的引用,指向变量nNumber。而当调用Forward(66)时,因为66是一个右值常量表达式,所以T被推断为int类型,arg成为一个右值引用(由于传入的是右值,此时实际上是隐式转换为了右值引用int&&),指向一个临时创建的整数对象。

#include <iostream>
using namespace std;template<typename T>
void Process(T arg)
{cout << arg << endl;
}template<typename T>
void Forward(T &&arg)
{// arg是一个万能引用,可以绑定到左值或右值Process(std::forward<T>(arg));
}int main()
{int nNumber = 66;// 在这里,T被推断为int&,arg绑定到左值xForward(nNumber);// 在这里,T被推断为int&&,arg绑定到右值临时对象Forward(66);return 0;
}

应用场景

        在C++中,完美转发常用于编写通用工厂函数,使得该函数能够接受任意类型和引用类型的参数,并无损地传递给目标构造函数。

#include <iostream>
#include <memory>
using namespace std;template<typename T, typename... Args>
std::unique_ptr<T> CreateObject(Args&&... args)
{return std::make_unique<T>(std::forward<Args>(args)...);
}class MyClass
{
public:MyClass(int a, const std::string& b) {}MyClass(const MyClass& other) {}MyClass(MyClass&& other) noexcept {}
};int main()
{auto obj1 = CreateObject<MyClass>(66, "CSDN");return 0;
}

        在上面的示例代码中,CreateObject函数接收任意数量、任意类型的参数(通过模板参数包Args表示),并使用std::forward<Args>(args)...将这些参数无损地传递给T类型的构造函数。这意味着无论是左值还是右值,甚至是具有特定CV限定符的引用,都能正确地传递给目标构造函数。

        当调用CreateObject<MyClass>(66, "CSDN")时,实参66(右值)和"CSDN"(左值引用)会被完美地转发给MyClass的构造函数。如果传入的是右值临时对象,编译器会自动选择移动构造函数。如果是左值引用或普通值,则根据构造函数签名匹配相应的构造方式。

总结

        C++ 11引入的完美转发特性在提升代码的灵活性、简洁性和效率方面发挥了关键作用,特别是在现代C++中,开发者必须充分理解和熟练运用这一技术,才能编写出更加高效、可扩展的泛型代码。随着C++版本的不断更新,完美转发已经成为构建高性能库、设计组件化架构及编写高质量应用程序的重要基石。

相关文章:

C++ 11新特性之完美转发

概述 在C编程语言的演进过程中&#xff0c;C 11标准引入了一系列重大革新&#xff0c;其中之一便是“完美转发”机制。这一特性使得模板函数能够无损地传递任意类型的实参给其他函数或构造函数&#xff0c;从而极大地增强了C在泛型编程和资源管理方面的灵活性与效率。 完美转发…...

python222网站实战(SpringBoot+SpringSecurity+MybatisPlus+thymeleaf+layui)-友情链接管理实现

锋哥原创的SpringbootLayui python222网站实战&#xff1a; python222网站实战课程视频教程&#xff08;SpringBootPython爬虫实战&#xff09; ( 火爆连载更新中... )_哔哩哔哩_bilibilipython222网站实战课程视频教程&#xff08;SpringBootPython爬虫实战&#xff09; ( 火…...

【百度Apollo】探索自动驾驶:深入解析Apollo开放平台架构的博客指南

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…...

代理模式详解(重点解析JDK动态代理)

- 定义 在解析动态代理模式之前&#xff0c;先简单看下整个代理模式。代理模式分为普通代理、强制模式、动态代理模式。其中动态代理模式主要实现方式为Java JDK提供的JDK动态代理&#xff0c;第三方类库提供的&#xff0c;例如CGLIB动态代理。 代理模式就是为其他对象提供一种…...

【大厂AI课学习笔记】1.3 人工智能产业发展(2)

&#xff08;注&#xff1a;腾讯AI课学习笔记。&#xff09; 1.3.1 需求侧 转型需求&#xff1a;人口红利转化为创新红利。 场景丰富&#xff1a;超大规模且多样的应用场景。主要是我们的场景大&#xff0c;数据资源丰富。 抗疫加速&#xff1a;疫情常态化&#xff0c;催生新…...

【Python】一个简单的小案例:实现将两张图片合并为一张

使用时保证已经安装了opencv-python import cv2bg "BG.jpg" # 背景图名称 fg "FG.jpg" # 前景图名称 output_filename "new.jpg" # 合成后图片名称img_bg cv2.imread(bg) # 读取背景图 img_fg cv2.imread(fg) # 读取前景图# 读取背景…...

不同的强化学习模型适配与金融二级市场的功能性建议

DQN ES DDPG A2C TD3 SAC QMIX MADDPG PPO CQL IMPALA 哪个模型适合进行股票操作 在考虑使用哪种模型进行股票操作时&#xff0c;需要考虑模型的特点、适用场景以及实现复杂度等因素。以下是对您列出的几种强化学习模型的简要概述&#xff0c;以帮助您做出选择&#xff1a; DQ…...

【音视频原理】音频编解码原理 ③ ( 音频 比特率 / 码率 | 音频 帧 / 帧长 | 音频 帧 采样排列方式 - 交错模式 和 非交错模式 )

文章目录 一、音频 比特率 / 码率1、音频 比特率2、音频 比特率 案例3、音频 码率4、音频 码率相关因素5、常见的 音频 码率6、视频码率 - 仅做参考 二、音频 帧 / 帧长1、音频帧2、音频 帧长度 三、音频 帧 采样排列方式 - 交错模式 和 非交错模式1、交错模式2、非交错模式 一…...

spring常用语法

etl表达式解析 if (rawValue ! null && rawValue.startsWith("#{") && entryValue.endsWith("}")) { // assume its spel StandardEvaluationContext context new StandardEvaluationContext(); context.setBeanResolver(new Be…...

【计算机毕业设计】128电脑配件销售系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…...

换个思维方式快速上手UML和 plantUML——类图

和大多数朋友一样&#xff0c;Jeffrey 在一开始的时候也十分的厌烦软件工程的一系列东西&#xff0c;对工程化工具十分厌恶&#xff0c;觉得它繁琐&#xff0c;需要记忆很多没有意思的东西。 但是之所以&#xff0c;肯定有是因为。对工程化工具的不理解和不认可主要是基于两个逻…...

策略模式+SpringBoot接口,一个接口实现接收的数据自动分流处理

策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。策略模式的精髓就在于将经常变化的一点提取出来,单独变成一类,并且各个类别可以相互替换和组合。 1、策略接口 CalculationStrategy //算数 public interface…...

P1228 地毯填补问题(葬送的芙蓉王【bushi】)

地毯填补问题 题目描述 相传在一个古老的阿拉伯国家里&#xff0c;有一座宫殿。宫殿里有个四四方方的格子迷宫&#xff0c;国王选择驸马的方法非常特殊&#xff0c;也非常简单&#xff1a;公主就站在其中一个方格子上&#xff0c;只要谁能用地毯将除公主站立的地方外的所有地…...

352. 闇の連鎖(树上差分,LCA)

352. 闇の連鎖 - AcWing题库 传说中的暗之连锁被人们称为 Dark。 Dark 是人类内心的黑暗的产物&#xff0c;古今中外的勇者们都试图打倒它。 经过研究&#xff0c;你发现 Dark 呈现无向图的结构&#xff0c;图中有 N 个节点和两类边&#xff0c;一类边被称为主要边&#xff…...

dcat admin + dingo + nginx 开发前台

前言 Dcat Admin 是一个功能强大的后端框架&#xff0c;主要用于开发管理后台。然而&#xff0c;大多数网站不仅需要一个管理后台&#xff0c;还需要一个用户界面&#xff0c;即“前台”&#xff0c;以及它们自己的用户系统。 为了实现这一目标&#xff0c;我们需要对 Dcat A…...

安卓线性布局LinearLayout

<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"android:…...

Advanced CNN

文章目录 回顾Google NetInception1*1卷积Inception模块的实现网络构建完整代码 ResNet残差模块 Resedual Block残差网络的简单应用残差实现的代码 练习 回顾 这是一个简单的线性的卷积神经网络 然而有很多更为复杂的卷积神经网络。 Google Net Google Net 也叫Inception V…...

判断当前设备是不是安卓或者IOS?

代码(重要点): 当前文件要是 xxx.js文件,就需要写好代码后调用才会执行: // 判断是不是安卓 const isAndroid () > {return /android/.test(navigator.userAgent.toLowerCase()); }// 判断是不是ios const isIOS () > {return /iphone|ipad|ipod/.test(navigator.use…...

使用C++操作Matlab中的mat文件

matlab提供读写MAT文件的头文件和库函数&#xff0c;下面列出这些文件的路径&#xff0c;其中matlabroot指matlab安装的路径&#xff0c;arch来识别平台架构 头文件在matlabroot\extern\include库函数在matlabroot\bin\win64例程在matlabroot\extern\examples\eng_mat头文件 …...

【OCPP】ocpp1.6协议第3.5章节:本地授权和离线行为-介绍及翻译

目录 3.5章节 概述 3.5 本地鉴权和离线行为-译文(Local Authorization & Offline Behavior) 3.5.1 鉴权缓存-译文(3.5.1. Authorization Cache) 3.5.2 本地鉴权列表-译文(Local Authorization List) 3.5.3 授权缓存和本地授权列表之间的关系-译文(Relation between A…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...