Field
それ自体から継承しません。むしろ、template<typename TYPELIST> Field
から継承しField<typename TYPELIST::Tail>
ます。テンプレート引数の2つのリストが異なる限り、問題ありません。
タイプリストは、可変個引数テンプレートが言語に追加される前に、テンプレートが(事実上)可変数の型引数を取ることを可能にする古風な方法でした。彼らは、LISP consセルに相当する単純な単一リンクリスト構造を実装しました。ここHead
で、は「ペイロード」タイプであり、リストの残りの部分はタイプリストまたはLISPに相当するタイプTail
のいずれかです。TypeListEnd
nil
私たちが持っていると仮定します
typename TypeList<int, TypeList<char, TypeList<float, TypeListEnd> > > MyTypeList;
ここでは、それがそれぞれ1番目と2番目のテンプレートパラメーターに対応するTypeList
テンプレート定義メンバーHead
とtypedefメンバーであると想定しています。Tail
template<typename Head, Tail> struct TypeList { typedef Head Head; typedef Tail Tail; };
閉じ角かっこはスペースで区切る必要があることに注意してください。これは、C ++ 03コンパイラでコンパイルする必要がある場合があるためです。これは>>
、テンプレートコンテキストでも常に右シフト演算子として解釈されます。
次に、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
、タイプリスト内のすべてのタイプがパブリック継承によって含まれるようになります。もちろん、そのようなもので何か役に立つことをすることstruct
は別の問題であり、読者のための練習として残されています。