可变参数模板

一、基本语法

声明一个带有可变参数个数的模板的语法如下所示:

template<typename ...Element> class tuple;

tuple<int, string> a;  // use it like this

在模板参数 Element 左边出现省略号 ... ,就是表示 Element 是一个模板参数包(template type parameter pack).parameter pack(参数包)是新引入 C++ 中的概念,比如在这个例子中,Element 表示是一连串任意的参数打成的一个包.比如第2行中,Element 就是 int, string这个参数的合集.不仅“类型”的模板参数(也就是typename定义的参数)可以这样做,非类型的模板参数也可以这样做.比如下面这个例子:

template<typename T, unsigned PrimaryDimesion, unsigned...Dimesions>

class array { /**/ };

array<double, 3, 3> rotation_matrix; //3x3 ratiation matrix

现在我们知道parameter pack了,怎么在程序中真正具体地去处理打包进来的“任意个数”的参数呢?

原来以为,编译器会提供一些像get_param<1>(Element) 之类的内建的“参数抽取函数”给程序员使用,结果不是!!

看来我的思路还是太“过程式了”.其实 C++11 用的是 unpack 和类似函数重载似的“模板特化”来抽取参数的.

这是应用 variadic tempate 最“坑爹”的部分,因为它要求对“递归”和“人肉代码展开”有一定的功力啊.还是看例子吧:

template<typename... Elements> class tuple;

template<typename Head, typename... Tail>

class tuple<Head, Tail...> : private tuple<Tail...>

//这里应该算模板的特化,可变参数的模板特化时参数个数可能与声明时的模板参数个数不一致,因为是可变参数模板所以是可以编译通过,普通模板如此特化编译是通不过的.

{

Head head;

public:

/* implementation */

};

template<>

class tuple<>

{

/* zero-tuple implementation */

};

第1行声明了一个可以对应任意参数的tuple类,第2行到7行声明了这个类的一个部分特化,注意,这就是抽取参数的典型方法了.给个图还是最方便用来理解的:

只说明一下针对 parameter pack 相对的另一个概念,模板参数后面带省略号 ... 就是一个解包(unpack),会把这个参数所表示的参数列表解开后去匹配新的模板,或是进行模板展开.

时间: 2024-10-20 03:37:59

可变参数模板的相关文章

函数模板,函数模板重载,可变参数模板,函数模板覆盖,通过引用交换数据

 1.函数模板初级,如果想使用模板,需要实例化,实例化的方式是加上<数据类型> #include <iostream> //函数模板可以对类型进行优化重载,根据类型会覆盖 //如果仍然要使用模板函数,需要实例化 template<class T> T add(T a, T b) { std::cout << "T add " << std::endl; return a + b; } int add(int a, int

c++ --可变参数模板

一个可变参数模板就是一个可接受可变数目参数的模板函数或模板类. 可变数目的参数被称为参数包. 1 //可变参数模板;sizeof ...()运算符 2 template <typename ... Args> 3 void g(Args ... args) 4 { 5 cout<<sizeof ...(Args)<<endl; //类型参数的数目 6 cout<<sizeof ...(args)<<endl; //函数参数的数目 7 } 8 9

C++中的可变参数模板

作者:Eli Bendersky http://eli.thegreenplace.net/2014/variadic-templates-in-c/ 回到C++11前夜,编写带有任意参数函数的唯一办法是使用可变参数函数,像printf,使用省略号语法(-)以及伴随的va_族的宏.如果你曾经使用这个方法编写代码,你会知道这有多累赘.除了变成类型不安全外(所有的类型解析必须在运行时在va_arg里通过显式转换来完成),要做对并不容易.Va_宏执行低级的内存操作,我看见过许多因为没有小心使用它们导致

求变量的数据类型,typeid,bool,C和C++的不同,new和delete,C++中的枚举,inline和可变参数模板,auto和函数模板,宽字符

求变量的数据类型,通过函数typeid(变量名).name();获得变量的数据类型. 案例如下: #include <iostream> #include <stdlib.h> void main() { double db = 10.9; double *pdb = &db; auto num = pdb; //通过typeid的方式获得数据类型 std::cout << typeid(db).name() << std::endl; std::c

C++11新特性之五——可变参数模板

有些时候,我们定义一个函数,可能这个函数需要支持可变长参数,也就是说调用者可以传入任意个数的参数.比如C函数printf(). 我们可以这么调用. printf("name: %s, number: %d", "Obama", 1); 那么这个函数是怎么实现的呢?其实C语言支持可变长参数的. 我们举个例子, double Sum(int count, ...) { va_list ap; double sum = 0; va_start(ap, count); fo

c++11——可变参数模板

在c++11之前,类模板和函数模板只能含有固定数量的模板参数,c++11增加了可变模板参数特性:允许模板定义中包含0到任意个模板参数.声明可变参数模板时,需要在typename或class后面加上省略号"...".     省略号的作用有两个: 1. 声明一个参数包,这个参数包中可以包含0到任意个模板参数 2. 在模板定义的右边,可以将参数包展开成一个一个独立的参数 1. 可变参数模板函数 可变参数模板函数的定义如下: template<class... T> void f

C++11 可变参数模板

在C++11之前, 有两个典型的受制于模板功能不强而导致代码重复难看的问题, 那就 function object 和 tuple. 拿 function objects 来说, 需要一个返回类型参数及N个参数类型参数. 但因为变长参数模板不受支持,导致不得不重复书写7.8个模板类,但最终也只能支持7.8个参数的 function object.C++11中最终为我们带来了强大的变长 参数模板功能,这些问题也随之迎刃而解了. 可变参数模板(Variadic Template)故名思义,即可以接受

C++11中的Tuple和可变参数模版

C++11中的tuple是一个n元的可变元组,它相当于有n个元素的结构体,只不过这个结构体的成员都是匿名的,tuple中提供了一个get()方法来获取某个下标对应的元素的值.另外可以通过make_tuple()方法来构造一个tuple对象.具体用法如下 我们知道tuple中的元素个数是不确定的,而每个元素的类型通过模板参数指定,那么tuple是如何做到这些的呢?答案就是使用可变参数模板.在C++中,我们使用过printf函数,它的参数就是可变的,在C++11中也允许模板的参数也是可变的.举个例子

C++ 11可变参数接口设计在模板编程中应用的一点点总结

概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量(或属性,C#中属性和成员变量还是有区别的): 类的成员方法: 从编译器的角度看,我们必须明确指定以上3部分,才算完整地定义了一个类并且编译通过. 所谓的“类弱化”,是指类的设计者在定义类的时候,并没有完整定义一个类,而是把类的其中一部分的定义留给类的使用者. 从传统才c++98看,通过模板类,使用