-
折叠参数:. . . (折叠参数的写法)
-
可增长(可以理解为可变参)模板参数的 模板函数(类似 c 语言的 print 函数,print 函数的参数也是可以增长的)
可变参函数,一般在函数模板当中去使用,用两个类型去做解析
-
可增长模板参数的 类模板
. . . Args 代表一个参数包,可以允许使用任何类型
1.如何通过参数包定义一个变量:Args . . . args【变量名】 如何通过 _Ty 类型定义变量: _Ty one
2.如果使用参数包:args. . . (必须是参数包名 + . . . 的方式去使用,其他用法是错误的) 如何使用普通变量:one
参数包的展开:
1.递归的方式展开,自动做一个参数包的剥离过程
2.采用列表方式进行剥离参数
#include <iostream>
using namespace std;
//由于没办法结束递归,所以需要准备一个递归终止函数-> 由于最后一个参数没要办法再剥离成两个参数
//需要写一个递归终止函数去接收只有一个参数的情况从而终止递归
template <class _Ty>
void print(_Ty data)
{
cout << data << endl;
}
//第一个是已知类型 第二个是折叠参数类型:...加类型名代表多个未知类型的参数包 本身需要两个参数
template <class _Ty, class ...Args>
void print(_Ty data, Args ...args) //参数包传3个不同的类型 {1,"string",1.1}
{
//打印数据
cout << data << "\t"; //data=1 把第一个参数剥离给data 打印1 参数包中还剩两个参数 {"string",1.1}
//递归调用:把参数包当作函数参数-> 为了剥离参数包
print(args...); //data="string" 参数包中还剩一个参数 {1.1}
//递归没有结束条件:只有一个参数的时候就没办法做剥离 因为函数需要两个参数没办法自己形成递归
}
int main()
{
//函数的参数是可以改变的
print(1, 2, 3, "string");
//传什么类型都可以:可以打印任何类型的数据类型,并且多少个都没有影响
print(1, "string", 2, 3);
//传几个都没影响 参数没有限制并且参数的类型也是没有限制的-> 由于我们用的是模板
print(1, 2);
print(1, 2,"ILove","Ilove");
print("ILove", "Ilove", "ILove", "Ilove", "ILove", "Ilove");
return 0;
}
/* 输出 */
1 2 3 string
1 string 2 3
1 2
1 2 ILove Ilove
ILove Ilove ILove Ilove ILove Ilove
采用列表的方式
逗号表达式取的是最后一个有效的值
//中间函数做参数包的解析(传一个函数参数的类型来做解析)
template <class _Ty>
void printData(_Ty data)
{
//负责做打印
cout << data << "\t";
}
//打印参数包:定义参数包类型的变量
template <class ...Args>
void printArgs(Args ...args)
{
//有多个(printData(args), 0)这个的参数 每次调用都会剥离一个参数出来 列表的第一个数据初始化为0
//initializer_list可增长:有多少个参数都可以打印
//列表数据可以重复调用 参数包有多少个就有多少个这样的调用方式
initializer_list<int>{(printData(args), 0)...};
//用数组的方式展开
//int array[] = { (printData(args), 0)... };
}
int main()
{
printArgs(1, 2, 3, "string");
printArgs(1, "string", 2, 3);
printArgs(1, 2);
printArgs(1, 2, "ILove", "Ilove");
printArgs("ILove", "Ilove", "ILove", "Ilove", "ILove", "Ilove");
return 0;
}
/* 输出 */
1 2 3 string
1 string 2 3
1 2
1 2 ILove Ilove
ILove Ilove ILove Ilove ILove Ilove