6

我从朋友那里得到了一段代码。但我真的很困惑,一个结构怎么能从自己继承呢?继承有意义吗?

template<class TYPELIST>
struct Field : public Field<typename TYPELIST::Tail> {
  typedef TYPELIST TypeListType;
  typename TypeListType::Head item_;
};

template<>
struct Field<TypeListEnd> {
};

我不知道这里发生了什么。

4

2 回答 2

10

Field不从自身继承;相反,template<typename TYPELIST> Field继承自Field<typename TYPELIST::Tail>. 只要两个模板参数列表是不同的就可以了。

在可变参数模板被添加到语言之前,类型列表是一种允许模板(实际上)采用可变数量的类型参数的古老方法。他们实现了一个简单的单链表结构,相当于 LISP 的 cons 单元,其中Head“有效负载”类型和Tail列表的其余部分是类型列表或TypeListEnd类型,相当于 LISP nil

假设我们有

typename TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > > MyTypeList;

这里我假设TypeList是一个模板定义HeadTailtypedef 成员分别对应于它的第一个和第二个模板参数:

template<typename Head, Tail> struct TypeList { typedef Head Head; typedef Tail Tail; };

请注意,我必须用空格分隔右尖括号,因为这可能必须在 C++03 编译器上编译,>>即使在模板上下文中也总是被解释为右移运算符。

然后你的Field元函数,当调用 on 时MyTypeList,将扩展为

Field<MyTypeList>;

Field<typename TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > > >;

struct Field<...>: TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > >::Tail {
    TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > >::Head item;
};

struct Field<...>: TypeList<char, TypeList<float, TypeListEnd> > {
    int item;
};

...

struct Field<...>: struct Field<...>: struct Field<...>: struct Field<TypeListEnd> {
} {
    float item;
} {
    char item;
} {
    int item;
};

这为您提供了struct通过公共继承包含类型列表中的所有类型。当然,用这样的 a 做任何有用的事情struct是另一回事,留给读者作为练习。

于 2012-06-25T01:05:31.280 回答
2

当你有一个类模板template <typename X> class SomeTemplate时,类类型SomeTemplate<A>SomeTemplate<B>是两个完全不同的、不相关的类类型(假设AB是不同的)。由于它们是两种完全不同的类型,因此其中一种继承自另一种并没有错。SomeTemplate<A>可以继承自SomeTemplate<B>,而后者又可以继承自SomeTemplate<C>等等,只要它在某些时候不会成为自引用的。

换句话说,在你的例子struct中并不像你所相信的那样从自身继承。你的例子中根本没有struct。相反,您的示例有几个s 模板structstruct当且仅当它们被专门化时,即当所有模板参数都被替换为实际类型时,这些模板才变为s。由于继承,该专业化可能会变成合法或非法,具体取决于其他详细信息(您没有提供)。

于 2012-06-25T01:31:58.317 回答