服务端视角的C++从入门到精通(十三)

110 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

可变参数模板

可变参数模板是C++11中引入的新特性。

#include <iostream>
using namespace std;

template <typename... T>
void func1(T... args)
{
	cout << sizeof...(T) << endl;
	cout << sizeof...(args) << endl;
}

void func2()
{
}

template <typename T, typename... U>
void func2(T v, U... args)
{
	cout << "test" << v << endl;
	func2(args...);
}

void testTemplate()
{
	func1(4, 5, 6);
	func2(1, 2, 3);
}

int main() {
    testTemplate();
    return 0;
}

这里就使用到了sizeof...这种“操作”。之所以叫“操作”,其实是因为它不仅仅是C++中的保留关键字,还是运算符,但总之不是函数。原因其实很简单,因为sizeof int这种语法是支持的,而函数绝不可能支持这种语法。而且,对sizeof的计算,其实在编译期就已经完成了,并非在运行时才实时进行计算,而由于C++语言强类型的特点,一旦代码确定,那么某个变量在整套代码中的类型也就确定下来了,自然可以使用sizeof获取它的大小。这里的...其实是和入参中的T...是对应的,代表着是对可变参数的长度进行计算。这里可以注意到,template声明中的typename... Tfunc1中的T...是对应的,而args则是形参名称。对于func2的调用而言,则是利用了递归的方法,每次从头部取一个参数出来进行相应打印操作,这里的递归变量其实就是入参个数,递归终点则是无参同名函数。可以看到,在将可变参数args传入func2的时候,也是需要加...的,以表示这个变量的变长特性。这里一个比较典型的应用就是可以用来改写标准C中的printf,本来只能使用复杂且容易出错的宏来实现,现在则可以借助可变参数模板实现。这也就是C++相对于C语言的一大特点,那就是相对来说更优雅一些、模块感更强,毕竟是OO语言。