I got a piece of code from my friend. But I am really confused, how can a struct inherit from itself? Does the inheritance make much sense?
template<class TYPELIST>
struct Field : public Field<typename TYPELIST::Tail> {
typedef TYPELIST TypeListType;
typename TypeListType::Head item_;
};
template<>
struct Field<TypeListEnd> {
};
I don't know what's going on here.
Field
doesn't inherit from itself; rather, template<typename TYPELIST> Field
inherits from Field<typename TYPELIST::Tail>
. It's fine as long as the two lists of template arguments are distinct.
Typelists were an archaic method of allowing templates to (in effect) take a variable number of type arguments, before variadic templates were added to the language. They implemented a simple singly linked list structure, equivalent to LISP cons cells, where Head
was the "payload" type and Tail
the remainder of the list, which would either be a typelist or a TypeListEnd
type, equivalent to LISP nil
.
Suppose we have
typename TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > > MyTypeList;
Here I'm assuming that TypeList
is a template defining Head
and Tail
typedef members corresponding to its first and second template parameters respectively:
template<typename Head, Tail> struct TypeList { typedef Head Head; typedef Tail Tail; };
Note that I'm having to space-separate the closing angle brackets, as this might have to be compiled on a C++03 compiler, where >>
is always even in template context interpreted as the right-shift operator.
Then your Field
metafunction, when invoked on MyTypeList
, will expand into
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;
};
This provides you with a struct
containing by public inheritance all of the types in your typelist. Of course, doing anything useful with such a struct
is another matter and is left as an exercise for the reader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With