C++11新特性:可变参数模板
2016-07-25 19:27
232 查看
C++11新标准增加了可变参数模板,它让我们可以创建可接受可变数量的参数的模板函数和模板类。本文试着较为详尽地介绍可变参数模板函数。
首先,C++11提供了一个用省略号表示的元运算符(…),它可以让我们声明表示模板参数包的标识符。模板参数包其实是一个类型列表的省略(因为编写的时候不知道有多少参数)。同时,元运算符还能让我们声明能够表示函数参数包的标识符。函数参数包其实是一个值列表。
其中Args是一个模板参数包而args是一个函数参数包。
Args可以与任意数量的类型匹配。如
即是说,这意味着函数参数包args包含的值列表与模板参数包Args包含的类型列表匹配,无论是类型还是数量。在上面的示例中,args包含值’s’、90、“sweet”和4.3。
另外,上述可变参数模板show_list1()可以与下面的函数调用相匹配:
就最后一个函数的调用而言,模板参数包Args包含类型int,int,int,int,const char*和std::string,而函数参数包args包含值2,4,6,8,”who do we”和std::string(“APPLE”)。
核心的理念是,将函数参数包展开,对列表中的第一项进行处理,再将余下的内容传递给递归调用,以此类推,直到列表为空。与常规递归一样,确保递归将终止很重要。这里的技巧是将模板头改为如下所示:
show_list3()的第一个实参决定了T和value的值,而其他参数决定看了Args和args的值,因为他们的类型和值被打包在里面。
通过改进,可以让函数对第一个参数进行处理,如显示它。然后,可递归调用show_list3(),并以args… 的方式将其他实参传递给它。每次递归都将显示一个值,并传递缩短了列表,直到列表为空为止。
下面的程序简单的演示了可变模板函数的这个用法:
当然,可变参数模板的引用形式为:
首先,C++11提供了一个用省略号表示的元运算符(…),它可以让我们声明表示模板参数包的标识符。模板参数包其实是一个类型列表的省略(因为编写的时候不知道有多少参数)。同时,元运算符还能让我们声明能够表示函数参数包的标识符。函数参数包其实是一个值列表。
template <typename... Args> void show_list1(Args... args) { ... }
其中Args是一个模板参数包而args是一个函数参数包。
Args可以与任意数量的类型匹配。如
show_list1('s', 90, "sweet", 4.3);//参数包Args与函数调用中的参数类型匹配:char、int、const char *和double。 //而下面的代码指出args的类型为Args: void show_list1(Args... args);
即是说,这意味着函数参数包args包含的值列表与模板参数包Args包含的类型列表匹配,无论是类型还是数量。在上面的示例中,args包含值’s’、90、“sweet”和4.3。
另外,上述可变参数模板show_list1()可以与下面的函数调用相匹配:
show_list1(); show_list1(99); show_list1(88.7,"cat"); show_list1(2,4,6,8,"who do we",std::string("APPLE"));
就最后一个函数的调用而言,模板参数包Args包含类型int,int,int,int,const char*和std::string,而函数参数包args包含值2,4,6,8,”who do we”和std::string(“APPLE”)。
可变参数模板和递归
可变参数模板的一个用法就是和递归结合,从而相继对函数参数包中的每个参数进行操作。核心的理念是,将函数参数包展开,对列表中的第一项进行处理,再将余下的内容传递给递归调用,以此类推,直到列表为空。与常规递归一样,确保递归将终止很重要。这里的技巧是将模板头改为如下所示:
template<typename T, typename... Args> void show_list3(T value, Args... args)
show_list3()的第一个实参决定了T和value的值,而其他参数决定看了Args和args的值,因为他们的类型和值被打包在里面。
通过改进,可以让函数对第一个参数进行处理,如显示它。然后,可递归调用show_list3(),并以args… 的方式将其他实参传递给它。每次递归都将显示一个值,并传递缩短了列表,直到列表为空为止。
下面的程序简单的演示了可变模板函数的这个用法:
#include "iostream" #include "string" using std::cout; using std::endl; using std::string; template <typename T> void show_list(T value) { //当args包只有一项时,将调用这个版本 cout << value << endl; } //也可以声明这样一个函数来结束递归:void show_list() {},当args包为0时,将调用这个版本以结束递归 template <typename T, typename... Args> void show_list(T value, Args... args) { cout << value << ", "; show_list(args...); } int main() { int n = 14; double x = 2.4; string mr = "something"; show_list(x * x, n, '!', 7, mr); return 0; }
当然,可变参数模板的引用形式为:
template<typename... Args> show_list(const Args&... args); //这将对每个函数参数应用const模式,如const int & n
相关文章推荐
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- C++11的for循环,以及范围Range类的简单实现
- C++11的新特性简单汇总介绍 (二)
- C++11的新特性简单汇总介绍 (一)
- 在 Qt4 中使用 C++11
- c++11新特性--decltype auto
- centos安装devtoolset-3支持gcc 4.9.2
- c++11学习笔记
- 使用eclipse编译含有C++11特性的代码
- 怎样在Linux环境编译支持C11
- eclipse支持c++11
- C++11可变参数函数与for循环
- vs2013 编译c++是发现惊天bug
- 简单性能测试函数模板
- 关于C++现状的一些思考
- 用C++11优化矩阵运算的空间和时间效率
- c++11之regex:初识regex
- 浅析构造函数之默认构造函数
- C++11新特性学习笔记
- c++中返回数组的函数