可变长度模板参数列表?

时间:2009-10-02 20:03:52

标签: c++ templates c++11 variable-length

我记得做过这样的事情:

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

也就是说,X继承自作为模板参数传递的可变长度的类型名列表。当然,这段代码是假设的。

但是,我找不到任何参考资料。可能吗?是C ++ 0x吗?

4 个答案:

答案 0 :(得分: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> {};

然后你正确定义了一般模板(之前你只是前向声明的):

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

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

更新:只是有一种奇怪的感觉我之前发布了类似的内容,and guess what...

答案 1 :(得分:19)

听起来你指的是C ++ 0x Variadic Templates。您也可以使用来自TypeList的Alexandrescu的Loki构造来实现相同的效果。

我相信有问题的可变参数模板语法如下所示。

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

答案 2 :(得分: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
{
...
};

答案 3 :(得分:2)

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

顺便说一句,如果你需要一个关于如何实现Earwicker所描述的继承机制的正式参考,那就在书C++ Templates上。