2009-10-02 122 views
10

我记得seing这样的事情正在做:可变长度模板参数列表?

template <ListOfTypenames> 
class X : public ListOfTypenames {}; 

即X从作为模板参数传递typenames的可变长度列表继承。这个代码当然是假设的。

我找不到这方面的任何引用,虽然。可能吗?它是C++ 0x吗?

回答

23

可以在当前的C++做。你给的模板参数的“足够大”数量,以及你给他们的默认值:

class nothing1 {}; 
class nothing2 {}; 
class nothing3 {}; 

template <class T1 = nothing1, class T2 = nothing2, class T3 = nothing3> 
class X : public T1, public T2, public T3 {}; 

或者你也可以变得更加复杂和使用递归。首先,你向前声明模板:

class nothing {}; 

template <class T1 = nothing, class T2 = nothing, class T3 = nothing> 
class X; 

然后你专注的,所有的参数都是默认的情况下:

template <> 
class X<nothing, nothing, nothing> {}; 

然后你正确定义的通用模板(之前你已经只向前-declared):

template <class T1, class T2, class T3> 
class X : public T1, public X<T2, T3> 

注意如何在基类,你继承了X,但你错过了第一个参数。所以他们都在一个地方滑动。最终它们都将是默认值,并且专业化将会启动,它不会继承任何东西,从而终止递归。

更新:只是有一种奇怪的感觉,我会发布这样的事情之前,and guess what...

+0

你也可以只使用一个“无中生有”类 – sellibitze 2009-10-02 20:25:45

+0

@sellibitze - 我只用一个“无”类中递归版本。您不能在非递归版本中使用相同的类作为默认值,因为您会得到“没有任何东西是直接基类”的错误。 – 2009-10-02 20:33:36

+0

我不明白:为什么从X继承时跳过第一个参数? – Gili 2010-07-03 01:27:49

19

听起来像是你指的C++ 0x Variadic Templates。您也可以使用Alexandrescu的的TypeList结构从Loki达到同样的效果。

我相信,在有关的可变参数模板语法看起来像下面这样。

template <typename...T> 
class X : public T... {}; 
+13

如果我没有弄错,你还需要解压类型:'public T ... {};'' – UncleBens 2009-10-02 21:12:52

2

可变数量的模板是下一个C++标准的一部分。但是,如果您使用GCC(从版本4.3开始),您可以体验它。这是一个list of available C++0x features in GCC。您正在寻找可变数据模板。

顺便说一句,如果您需要关于如何实现Earwicker描述的继承机制的正式参考,请参阅C++ Templates

4

正如其他人已经回答了,可变参数模板是一个标准的一部分,但在当前的C++进行仿真。一个便利的工具是使用Boost.MPL库。在你的代码中,你编写了一个模板参数(我们将其命名为“Typelist”),然后你的模板用户用MPL序列包装这个类型列表。示例:

#include "YourType.h" 
#include "FooBarAndBaz.h" 
#include <boost/mpl/vector.hpp> 

YourType<boost::mpl::vector<Foo, Bar, Baz> > FooBarBaz; 

在实现“YourType”时,可以使用各种元功能访问Typelist中的元素。例如,at_c<Typelist, N>是列表的N个元素。再举一个例子,在你的问题中的“X”级可以用inherit_linearly为写:

//Warning: Untested 
namespace bmpl = boost::mpl; 
template<class Typelist> 
class X : bmpl::inherit_linearly<Typelist, bmpl::inherit<bmpl::_1, bmpl::_2> >::type 
{ 
... 
};