所在的位置: C++ >> C++市场 >> C可变的函数参数

C可变的函数参数

#Cpp#

在笔者介绍C++11的那篇文章中,关于列表初始化那一节里的示例代码使用了C语言可变参数函数的性质,也就是可以声明参数的数量甚至是类型都是不确定的函数。

上图第二个构造函数就是一个具有不确定参数的函数,在C语言中通常称为缺省参数,要使用C语言的这个特性,首先需要包含头文件stdarg.h,从而可以通过使用三个宏va_start,va_arg和va_end来初始化、操作和回收参数指针。不过C语言的缺省参数特性有一个问题,就是通常并不能自动判断缺省的参数有多少个,虽然部分编译器会把参数为初始化的bit全部初始化为1,借此可以判断什么时候结束循环,但是这属于标准未定义行为,不同的编译器并不一样,因此上图的程序中使用了模板参数intN来指定参数个数。有没有办法不指定参数个数,让编译器自己判断有多少个参数呢,C语言的话,笔者不太清楚有没有;不过C++11的话,用能够展开参数的函数模板可以实现这一特性。

函数模板的声明通常如下图所示

而能够展开的函数模板通常声明为类似下面这样

...可以认为是一个运算符,用来表示展开。声明时放在前面表示对类型展开,使用时放到后面表示对参数进行展开。什么意思呢,就是typename...Args表示可能有多个模板参数,编译器在对函数模板实例化的时候会将typename...Args展开成多个类型,比如typenamea,typenameb,然后fun里面的Args...args变为aargs1,bargs2,而下面的args...则会变成a,b。这就是声明时将类型展开,类型放在前面,于是三个点也放在前面,使用时将参数展开,因为放前面是展开类型,所以规定放后面是展开参数。

上面两幅图的fun函数具体执行过程的话,比如fun(1,2,3,4,5),会先执行fun(1,2,3,4,5)然后调用fun(2,3,4,5)然后是fun(3,4,5),fun(4,5),fun(5)然后结束。fun调用的次数是一个固定值,就是参数的个数,不过具体使用的模板,fun(1,2,3,4,5)~fun(4,5)都是用的第二个模板,fun(5)用的是第一个模板,这样可以保证编译通过,因为args个数为0的时候调用fun(args...)导致相当于调用fun(),而实际上没有这个重载。

如果我们使用C++11的这个特性来重新编写之前的Array类,代码可以参考如下。

然后我们就可以类似标准库的vector用Arrayinta={1,2,3,4}来初始化这个数组了。




转载请注明:http://www.aierlanlan.com/rzdk/1299.html