C++ Variadic Templates(可变参数模板)

本文参考侯捷老师的视频:https://www.youtube.com/watch?v=TJIb9TGfDIw&list=PL-X74YXt4LVYo_bk-jHMV5T3LHRYRbZoH
以及C++ primer第五版 相关内容。

可变参数模板函数

//递归的终止条件
void print() {}
//Variadic Templates
//一般用于递归处理
template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args) {
	cout << firstArg << endl;
	print(args...);
}

上面这个模板函数可以接收任意个数任意类型的参数并进行打印输出。其中typename... Types是可变模板参数,表示可以接收任意类型,Types... args表示可变函数参数,表示可以接收任意个数、任意类型的参数,要注意...在不同的位置,这些都是固定的。可以看到我们输出第一个参数以后,调用了print(args...),如果args中的参数个数大于0,则会继续调用模板函数,将第一个参数赋给firstArg,其余参数赋给args;如果参数个数等于0,则调用非模板函数void print()结束递归。

可以看出,可变参数模板函数是通过递归来进行参数解包的。

特殊的,如果我们将上面的函数写成下面的版本:

//递归的终止条件
template<typename T>
void print(const T& t) {
	cout << t << endl;
}
//Variadic Templates
//一般用于递归处理
template<typename T, typename... Types>
void print(const T& t, const Types&... args) {
	print(t);
	print(args...);
}

同样完成将所有参数进行打印的工作。但是可能会有疑惑,对于print(t),似乎既可以调用void print(const T& t),又可以调用void print(const T& t, const Types... args),那么编译器会调用哪一个呢?这个是确定的,编译器会调用void print(const T& t)。原因在于非可变参数版本比可变参数版本更加特例化。(详细模板重载规则见C++ primer 16.3 重载与模板)
在可变参数模板函数中,我们可以通过sizeof...(args)获得可变参数的个数,返回一个常量表达式。

如果运行下面的代码,仍然会和上面的有同样的效果,void print(const Types... args)不会运行:

//递归的终止条件
template<typename T>
void print(const T& t) {
    cout << t << endl;
}
//Variadic Templates
//一般用于递归处理
template<typename T, typename... Types>
void print(const T& firstArg, const Types&... args) {
    print(firstArg);
    print(args...);
}

template<typename... Types>
void print(const Types&... args) {
    cout << sizeof...(args) << endl;
}

可变参数模板类

最经典的就是tuple,通过递归地继承自己,实现了可以包含任意个数、任意类型的数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值