C++_可变参数模板

       

目录

1、可变参数模板的用法

2、参数包展开

2.1 递归方式展开

2.2 逗号表达式形式展开 

3、参数包的大小

结语 


前言:

        C++11引入了可变参数模板,他的作用是可以让创建的函数模板或者类模板的模板参数可以接收任意数量参数,在C++11前,只能手写固定数量个模板参数,并且只能接收与之对应数量的参数,有了可变参数模板后,代码就变得更加的灵活了。

1、可变参数模板的用法

        可变参数必须是搭配着模板使用的,具体写法如下:

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以接收多个实参。
template <class ...Args>
void ShowList(Args... args)
{}

         可以发现,可变参数模板的写法非常特殊,需要先创建一个模板,并且该模板的参数需要用三个点:’...‘来声明,如上代码,Args就成了一个模板参数包,再用该模板参数去作为args的类型,则args为函数形参参数包,这一类args就可以接收多个实参了(可接收0~n个参数,n>=0)。

2、参数包展开

        虽然args可以接收多个参数,但是无法直接读取这些参数的内容,因此最重要的一步是将args参数包中的内容展开并读取到里面的数据,这也是可变参数模板的一个难点——参数包的展开。

2.1 递归方式展开

        采用类似于递归的方式进行参数包的展开(注意调用参数包的写法),具体代码如下:

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;

template <class T>
void ShowList(const T& t)
{
	cout << t << endl;
}

template <class T, class ...Args>
void ShowList(T value, Args... args)//函数重载
{
	//展开参数包
	cout << value << " ";
	ShowList(args...);//当只剩下一个参数时会走第一个ShowList
}
int main()
{
	ShowList(1, 'A', string("hello world"));
	return 0;
}

         运行结果:

        具体流程如下图所示:

2.2 逗号表达式形式展开 

        除了上述的递归方式,还可以把参数包放到一个数组里, 写法如下:

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;

template <class T>
void PrintArg(T t)
{
	cout << t << " ";
}

template <class ...Args>
void ShowList(Args... args)
{
	int arr[] = { (PrintArg(args), 0)... };//特殊的写法
	cout << endl;
}
int main()
{
	ShowList(1, 'A', "hello world");
	return 0;
}

        运行结果:

        具体过程:{(printarg(args), 0)...}将会展开成((printarg(arg1),0), (printarg(arg2),0), (printarg(arg3),0), etc... ),因为是逗号表达式,所以先执行逗号前面的内容,即(printarg(args),因此会先去调用函数printarg,也就是说在构造arr数组的过程就将参数包展开了,并且该数组arr的全部元素都是0(因为逗号表达式的结果取最后一个),该数组的大小是参数包的大小,并且参数包中有多少个参数就有多少个元素0,数组的最终结果应该是:arr[sizeof...(args)] = {0,0,0..}。

3、参数包的大小

         参数包的大小即该参数包里总共有多少个参数,与参数的类型无关,只与个数有关,示例代码如下:

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;

template<class ...Args>
void func(Args... args)
{
	cout << __FUNCTION__ << ":" << sizeof...(args) << endl;//注意求参数包的写法
}

int main()
{
	func();//一个参数没有则参数包为0
	func('A', "hello world");//两个参数,参数包为2
	func(1,'A',"hello world");//三个参数,参数包为3
	return 0;
}

        运行结果:

        此处注意计算参数包的写法。 

结语 

        以上就是关于可变参数模板的讲解,比如当我们不知道要传多少个参数给到模板时,这类场景下就可以使用可变参数模板了,该模板参数可以接收任意数量个参数,然后再用特殊的写法将其内容展开就可以读取到参数包里的数据了。

        最后希望本文可以给你带来更多的收获,如果本文对你起到了帮助,希望可以动动小指头帮忙点赞👍+关注😎+收藏👌!如果有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

16. C++标准库

C标准库兼容C语言标准函数库&#xff0c;可以在C标准库中直接使用C语言标准函数库文件&#xff0c;同时C标准库增加了自己的源代码文件&#xff0c;新增文件使用C编写&#xff0c;多数代码放在std命名空间中&#xff0c;所以连接C标准库文件后还需要 using namespace std;。 【…

【OpenGL手册11】材质的模型

目录 一、说明二、材质表面和光照三、设置材质四、光的属性五、不同的光源颜色练习 一、说明 在现实世界里&#xff0c;每个物体会对光产生不同的反应。比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的…

Seata 2.x 系列【6】微服务项目搭建

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 数据库…

2024年3月ZZUACM 招新赛题解

2024年3月ZZUACM 招新赛 题号题目A区间次大值B上课签到C魔法森林&#xff08;一&#xff09;D魔法森林&#xff08;二&#xff09;ELOPF跳格子G猜数字H抽卡记录I安达的二维矩阵J安达的数字手术K跳楼梯L前缀和 A 区间次大值—循环/签到题 题目描述 给定一个 n n n的全排列 a i…

DeepLearning in Pytorch|共享单车预测NN详解(思路+代码剖析)

目录 概要 一、代码概览 二、详解 基本逻辑 1.数据准备 2.设计神经网络 初版 改进版 测试 总结 概要 原文链接&#xff1a;DeepLearning in Pytorch|我的第一个NN-共享单车预测 我的第一个深度学习神经网络模型---利用Pytorch设计人工神经网络对某地区租赁单车的使用…

自然语言处理: 第十三章P-tuing系列之P-tuning V1

项目地址: P-Tuning 论文地址: [2103.10385] GPT Understands, Too (arxiv.org) 理论基础 正如果上一节介绍LoRA(自然语言处理: 第十二章LoRA解读_lora自然英语处理-CSDN博客)一样,本次介绍的在21年由清华团推提出来的 P-Tuning V1系列也属于PEFT(参数高效微调系列)里的一种&…

【前端】平面转换与渐变

目录 1.字体图标 2.平面转换 2.1位移 2.2旋转 2.3多重转换 2.4缩放 3.渐变 1.字体图标 引入iconfont平台字体图标样式表 <link rel"stylesheet" href"./iconfont/iconfont.css"> <i class"iconfont xx"></i> 第一个类…

函数柯里化:JavaScript中的高级技巧

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

学习嵌入式C语言要掌握到什么程度?

学习嵌入式C语言要掌握到什么程度&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&#xff0c;让我不断提升自己&#…

anaconda问题合集

目录 一. 万分注意 二. ImportError: DLL load failed while importing _ctypes: 找不到指定的模块。 1. 发生情况 2. 导致结果和解决方法 三. WARNING: A newer version of conda exists. 1. 在conda install 某库的时候 2. 解决方法 一. 万分注意 不要轻易使用 conda …

YOLO建筑物损伤评估数据集

YOLO建筑物损伤评估数据集&#xff0c;重度损伤&#xff0c;轻微损伤&#xff0c;中度损伤&#xff0c;未损伤4类&#xff0c;近五千张图像&#xff0c;yolo标注完整&#xff0c;应用数据增强。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集…

举个栗子!Alteryx 技巧(10):解决连数据库时出现中文乱码的问题

在日常工作中&#xff0c;我们经常遇到需要连接 Oracle 数据库的场景。当采用 ODBC 的方式进行连接时&#xff0c;可能会出现中文乱码。那么&#xff0c;应该如何解决中文乱码这个问题呢&#xff1f; 本期《举个栗子&#xff01;Alteryx 技巧》&#xff0c;我们就来分享方法吧…

近年来文本检测相关工作梳理

引言 场景文本检测任务&#xff0c;一直以来是OCR整个任务中最为重要的一环。虽然有一些相关工作是端对端OCR工作的&#xff0c;但是从工业界来看&#xff0c;相关落地应用较为困难。因此&#xff0c;两阶段的OCR方案一直是优先考虑的。 在两阶段中&#xff08;文本检测文本识…

猫头虎分享已解决Bug || 云服务中断:CloudOutage, CloudProviderError

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

GO的运算符

点击名片关注 阿尘blog&#xff0c;一起学习&#xff0c;一起成长 Go语言中的运算符用于执行各种操作&#xff0c;如算术运算、比较、逻辑运算等。下面是Go语言中各类运算符的详细讲解&#xff0c;包括代码示例、代码说明以及使用注意事项。 1 算术运算符 加法运算符 a : 5 b …

Java实现从本地读取CSV文件数据

一、前言 最近项目中需要实现这样一个功能&#xff0c;就是从本地读取CSV文件&#xff0c;并以指定行作为标题行&#xff0c;指定行开始作为数据读取行&#xff0c;读取数据并返回给前端&#xff0c;下面具体说下是如何通过java实现。 二、如何实现&#xff1f; 1.引入相关mav…

西门子PLC中的程序块及类别详解

在PLC的编程中&#xff0c;程序块是指一组逻辑控制代码&#xff0c;用于实现系统中特定的控制功能。程序块主要分为四类&#xff0c;包括函数块&#xff08;FB&#xff09;、函数&#xff08;FC&#xff09;、数据块&#xff08;DB&#xff09;和组织块&#xff08;OB&#xff…

git讲本地代码提交到码云https://gitee.com/

首先需要在码云中自己账号下创建一个空的仓库 第一步 如下图 第二步 仓库名字和仓库是否私有&#xff0c;其他不用选 以上操作好了以后 回到本地&#xff0c;在本地你要上传到仓库的项目路径下&#xff0c;初始化为git 执行 git init 接着&#xff0c;把远程仓库地址复制下…

软件设计师软考题目解析24 --每日五题

想说的话&#xff1a;要准备软考了。0.0&#xff0c;其实我是不想考的&#xff0c;但是吧&#xff0c;由于本人已经学完所有知识了&#xff0c;只是被学校的课程给锁在那里了&#xff0c;不然早找工作去了。寻思着反正也无聊&#xff0c;就考个证玩玩。 本人github地址&#xf…

云原生构建 微服务、容器化与容器编排

第1章 何为云原生&#xff0c;云原生为何而生 SOA也就是面向服务的架构 软件架构的发展主要经历了集中式架构、分布式架构以及云原生架构这几代架构的发展。 微服务架构&#xff0c;其实是SOA的另外一种实现方式&#xff0c;属于SOA的子集。 在微服务架构下&#xff0c;系统…