变长函数
printf()使用了C语言的函数变长参数特性,通过使用变长函数(variadic funciton),printf的实现能够接受任何长度的参数列表。但变长参数对于传递参数的类型并不了解。此外printf不接受非内置类型。
变长函数示例如下:
// va_arg_test.cpp : 定义控制台应用程序的入口点。
//
//访问可变参数流程
//va_list args; //定义一个可变参数列表
//va_start(args,arg); //初始化args指向强制参数arg的下一个参数
//va_arg(args,type); //获取当前参数内容并将args指向下一个参数
//... //循环获取所有可变参数内容
//va_end(args); //释放args
#include <stdio.h>
#include <stdarg.h>
double SumOfFloat(int count, ...) {
va_list ap; double sum = 0;
va_start(ap, count); // 获得变长列表的句柄 ap
for (int i = 0; i < count; i++)
sum += va_arg(ap, double); // 每次获得一个参数
va_end(ap);
return sum;
}
int main() {
printf("%f\n", SumOfFloat(3, 1.2f, 3.4, 5.6)); // 10.200000
}
变长模板类
通过变长模板类实现多个整数相乘
#include <stdarg.h>
#include <string>
#include <iostream>
using namespace std;
template <long... nums>
struct Multiply;
template <long first, long... last>
struct Multiply<first, last...> {
static const long val = first * Multiply<last...>::val;
};
template <>
struct Multiply<> {
static const long val = 1;
};
int main(int argc, char* argv[])
{
cout << Multiply<2, 3, 4, 5>::val << endl; // 120
cout << Multiply<22, 44, 66, 88, 9>::val << endl; // 50599296 return 0; }/
system("pause");
return 0;
}
变长模板函数
用变长模板函数实现的输出函数Printf。
其可接受任意多个参数(包含非内置类型)。
#include <iostream>
#include <stdexcept>
using namespace std;
void Printf(const char* s) {
while (*s) {
if (*s == '%' && *++s != '%')
throw runtime_error("invalid format string: missing arguments");
cout << *s++;
}
}
template<typename T, typename... Args>
void Printf(const char* s, T value, Args... args)
{
while (*s) {
if (*s == '%' && *++s != '%') {
cout << value;
return Printf(++s, args...);
}
cout << *s++;
}
throw
runtime_error("extra arguments provided to Printf");
}
int main() {
Printf("hello %s\n",string("world")); // hello world
}
参考:
深入理解C++11:C++11新特性解析与应用
Michael Wong IBM XL编译器中国开发团队 著
ISBN:978-7-111-42660-8