10

我记得看到这样的事情正在做:

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

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

不过,我找不到任何参考。是否可以?是 C++0x 吗?

4

4 回答 4

24

您可以在当前的 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 但您错过了第一个参数。所以他们都沿着一个地方滑动。最终它们都将成为默认值,并且专业化将启动,它不会继承任何东西,从而终止递归。

更新:只是有一种奇怪的感觉,我以前发布过类似的东西,你猜怎么着......

于 2009-10-02T20:06:43.010 回答
19

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

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

template <typename...T>
class X : public T... {};
于 2009-10-02T20:09:14.293 回答
4

正如其他人已经回答的那样,可变参数模板是下一个标准的一部分,但可以在当前的 C++ 中进行模拟。一个方便的工具是使用Boost.MPL库。在您的代码中,您编写了一个模板参数(我们将其命名为“Typelist”),模板的用户将 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列表的第 th 个元素。作为另一个例子,您问题中的“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
{
...
};
于 2009-10-02T20:37:46.423 回答
2

可变数量的模板是下一个 C++ 标准的一部分。但是,如果您使用 GCC(从 4.3 版开始),您可以体验一下。这是GCC 中可用的 C++0x 功能列表。您正在寻找可变参数模板。

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

于 2009-10-02T20:14:03.510 回答