我记得看到这样的事情正在做:
template <ListOfTypenames>
class X : public ListOfTypenames {};
也就是说,X 继承自作为模板参数传递的可变长度类型名列表。当然,此代码是假设的。
不过,我找不到任何参考。是否可以?是 C++0x 吗?
我记得看到这样的事情正在做:
template <ListOfTypenames>
class X : public ListOfTypenames {};
也就是说,X 继承自作为模板参数传递的可变长度类型名列表。当然,此代码是假设的。
不过,我找不到任何参考。是否可以?是 C++0x 吗?
您可以在当前的 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 但您错过了第一个参数。所以他们都沿着一个地方滑动。最终它们都将成为默认值,并且专业化将启动,它不会继承任何东西,从而终止递归。
更新:只是有一种奇怪的感觉,我以前发布过类似的东西,你猜怎么着......
听起来您指的是 C++0x Variadic Templates。您还可以使用来自Loki的 Alexandrescu 的TypeList构造来实现相同的效果。
我相信有问题的可变参数模板语法如下所示。
template <typename...T>
class X : public T... {};
正如其他人已经回答的那样,可变参数模板是下一个标准的一部分,但可以在当前的 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
{
...
};
可变数量的模板是下一个 C++ 标准的一部分。但是,如果您使用 GCC(从 4.3 版开始),您可以体验一下。这是GCC 中可用的 C++0x 功能列表。您正在寻找可变参数模板。
顺便说一句,如果您需要有关如何实现 Earwicker 描述的继承机制的正式参考,请参阅C++ Templates一书。