首页 > 编程语言 >C++ 泛型编程之可变参数包

C++ 泛型编程之可变参数包

时间:2023-11-30 22:13:06浏览次数:52  
标签:... args 递归 编程 C++ print 参数 泛型 展开

C++ 泛型编程之可变模板参数


·variadic templates 可以表示0到任意个数、任意类型的参数

1.可变模板参数的展开:

template<typename... Args>	//可以将参数包展开一个个独立的参数
void func(Args... args);	//声明一个参数包Args... args 这个参数包可以包括0到任意个模板参数

1.1求参数包中参数的个数:若f()中未传入参数,size输出为0:

template <class... T>
void f(T... args)
{    
    cout << sizeof...(args) << endl; //打印变参的个数
}

f();       			//0
f(1, 2);    		//2
f(1, 2.5, "");    	//3

2.1递归函数方式展开参数包:

通过递归函数展开参数包,需要提供一个参数包展开的函数和一个递归终止函数,由递归终止结束递归:

#include <iostream>
using namespace std;
//递归终止函数
void print()
{
   cout << "empty" << endl;
}
//展开函数
template <class T, class ...Args>	// class ...Args :允许接收(0~N)个模板类型“T”
void print(T head, Args... rest)	//Args ...rest (0~N) 允许每个模板类型"T"接收(0~N)	
{									//个参数
   cout << head << endl;
   print(rest...);					//注意参数包调用时 ...参数包应在后面,可以理解一个接一个传
}									//入参数


int main(void)
{
   print(1,2,3,4);
   return 0;
}
--------------------------------------------
    打印结果:
    1
    2
    3
    4
   empty

解释:递归终止函数就是特化模板函数中参数包展开到最后一个的下一个的时候,当递归展开参数包结束后,函数原型为 func(parms) {假设func(parms)是展开函数},会变成func() 无参的形式,我们所要给出的递归终止函数就是这个。函数原型的无参形式!


2.1.2逗号表达式展开参数包

先理解逗号表达式:

 d = {a = b , c};

这个表达式的顺序为:b赋值给a,然后c做返回值赋值给d 既 a = b, d =c

因此利用这个执行顺序,我们可以初始化一个数组:

template<typename T>
void print(T t){
    cout<<t<<endl;
}

template<class ...Args>
void expand(Args ...args){
    int arr[] = {(print(args),0)...};
}

int main(){
    expand(1,2,3,4);
    return 0;
}
-----------------------------
    输出:
    1
    2
    3
    4

根据逗号表达式,先运行print(args),参数递归展开,第一个参数进入print执行打印参数,print(first_parm)运行结束,然后就是执行 int arr[] = {0};因为是递归展开第一层,arr只填入一个元素0,至此一轮递归结束。开始继续递归,直到运行prin(4),arr[]又填入一个元素0后,递归结束。至此expand运行结束,依次打印输出1,2,3,4,此外,arr在参数包展开的过程中,被初始化为int arr[ sizeof....(args) ],大小为4,元素都为0的数组。

标签:...,args,递归,编程,C++,print,参数,泛型,展开
From: https://www.cnblogs.com/XuefengMing/p/17868476.html

相关文章

  • C++20语言核心特性的变化
    usingforEnumerationValues  对比一下C++20前后的区别:enumclassState{open,progress,done=9};//BeforeC++20voidprint(States){switch(s){caseState::open:std::cout<<"open\n";brea......
  • 实验4 现代C++标准库与类模板
    实验任务5task5.cpp#include"Textcoder.hpp"#include<iostream>#include<string>voidtest(){ usingnamespacestd; stringtext,encoded_text,decoded_text; cout<<"输入英文文本:"; while(getline(cin,text)) { encoded_t......
  • 实验4 现代C++标准库与类模板
    四、实验内容1.实验任务1//在C++中定义和使用类模板task1_1.cpp#include<iostream>usingnamespacestd;//类A的定义classA{public:A(intx0,inty0):x{x0},y{y0}{}voidshow()const{cout<<x<<","<<y<<endl;}p......
  • 实验4 现代C++标准库与类模板
    实验任务1task1task1_1.cpp#include<iostream>usingstd::cout;usingstd::endl;classA{public:A(intx0,inty0):x{x0},y{y0}{}voidshow()const{cout<<x<<","<<y<<endl;}private:in......
  • C/C++ 实现FTP文件上传下载
    FTP(文件传输协议)是一种用于在网络上传输文件的标准协议。它属于因特网标准化的协议族之一,为文件的上传、下载和文件管理提供了一种标准化的方法,在Windows系统中操作FTP上传下载可以使用WinINet库,WinINet(WindowsInternet)库是Windows操作系统中的一个网络API库,用于访问Interne......
  • py01-linux编程
    一、Linux目录说明:1、/boot:存放Linux系统内核程序和启动程序2、/dev:存放设备文件3、/etc:存放系统配置文件4、/home:存放普通用户信息5、/root:存放管理员用户信息6、/bin:存放一般命令文件(多为普通用户使用)7、/sbin:存放系统命令(多为管理员使用)8、/lib:存放库函数文件(调用......
  • 零代码编程:用ChatGPT批量下载某个网页中的特定网页链接
    以lexfridman的官方网站为例,https://lexfridman.com/podcast/,如何批量下载网页呢?查看网页源文件,播客transcript的链接是:<ahref="https://lexfridman.com/jared-kushner-transcript">Transcript</a>文件标题在这里:<title>TranscriptforJaredKushner:Israel,Palestine,Hamas......
  • C++基础
    文章参考:《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)_白鳯的博客-CSDN博客C++运算符重载_c++重载=-CSDN博客一.C++基础1.一个简单的案例#include<iostream>//编译预处理命令usingnamespacestd;//使用命名空间intadd(inta,intb);//......
  • [转载]C/C++ 遍历窗口标题类名
    原地址:https://cloud.tencent.com/developer/article/2201930遍历每个进程,一次查找进程下的窗口,找到窗口标题为“”,窗口类名为“RunDll”的窗口。如果找到返回true,没找到返回false。#pragmaregion依赖typedefstructEnumHWndsArg{std::vector<HWND>*vecHWnds......
  • C++使用OpenSSL实现AES-256-CBC加密解密实例----亲测OK
    //AesUtil.h#ifndef__AES_UTIL_H__#define__AES_UTIL_H__#ifdef__cplusplus//告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的extern"C"{#endifstringUTIL_aes_cbc_encrypt(constunsignedchar*password,unsignedintpassword_byte_len,c......