我从朋友那里得到了一段代码。但我真的很困惑,结构如何从自身继承?继承是否有意义?
template<class TYPELIST>
struct Field : public Field<typename TYPELIST::Tail> {
typedef TYPELIST TypeListType;
typename TypeListType::Head item_;
};
template<>
struct Field<TypeListEnd> {
};
我不知道这里发生了什么。
答案 0 :(得分:9)
Field
不会继承自己;相反,template<typename TYPELIST> Field
继承自Field<typename TYPELIST::Tail>
。只要两个模板参数列表不同,就可以了。
类型列表是一种古老的方法,允许模板(实际上)在variadic templates添加到语言之前采用可变数量的类型参数。他们实现了一个简单的单链表结构,相当于LISP cons单元格,其中Head
是“有效载荷”类型,Tail
是列表的其余部分,可以是类型列表,也可以是{{1类型,相当于LISP TypeListEnd
。
假设我们有
nil
这里我假设typename TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > > MyTypeList;
是定义TypeList
和Head
typedef成员的模板,分别对应于第一个和第二个模板参数:
Tail
请注意,我必须将结束尖括号空格分开,因为这可能必须在C ++ 03编译器上进行编译,其中template<typename Head, Tail> struct TypeList { typedef Head Head; typedef Tail Tail; };
始终在模板上下文中被解释为右 - 转移运营商。
然后,在>>
上调用的Field
元函数将扩展为
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
做一些有用的事情是另一回事,留给读者练习。
答案 1 :(得分:2)
如果您有一个类模板template <typename X> class SomeTemplate
,那么类类型SomeTemplate<A>
和SomeTemplate<B>
是两个完全不同的,不相关的类类型(假设A
和B
是不同的)。由于它们是两种完全不同的类型,因此其中一种继承自另一种并没有错。 SomeTemplate<A>
可以继承SomeTemplate<B>
,而SomeTemplate<C>
可以继承struct
等等,只要它在某些时候不会自我引用。
换句话说,在您的示例中,struct
并不会继承自己,就像您似乎相信的那样。你的例子中根本没有struct
。相反,您的示例为struct
提供了几个模板。当且仅当它们专用时,即当所有模板参数都被实际类型替换时,这些模板变为{{1}}。由于继承,该专业化可能会变得合法或非法,具体取决于其他细节(您未提供)。