TypeList
ここでは、Lokiに記されているTypeListについての備忘録。
まずは、TypeListの基本となる構造から。
class NullType {};
template < typename H, typename T >
struct TypeList
{
typedef H Head;
typedef T Tail;
};
特に説明はいらないですね。
これを定義する方法は次のようにする。
typdef TypeList< int, NullType > tListType;
登録数が1つの場合はこうなる。
typedef TypeList< int, TypeList< char, TypeList< unsigned int, NullType > > > tListTyep;
登録数が3つにもなるとこうなる。
けどこれだと登録する数が増えると面倒なので以下のようなマクロを用意する。
#define TYPELIST_1(T1) TypeList < T1, NullType >
#define TYPELIST_2(T1, T2) TypeList < T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) TypeList < T1, TYPELIST_2(T2, T3) >
使い方は簡単。
typedef TYPELIST_3( int, char, unsigned int ) tListType;
次、
登録された型の数を数える方法は、次のような定義を用意する。
template < typename tList >
struct TypeListLength;
template < typename H, typename T >
struct TypeListLength < TypeList < H, T > >
{
enum { length = TypeListLength< T >::length + 1 };
};
template <>
struct TypeListLength < NullType >
{
enum { length = 0 };
};
で、以下のように使う。
int len = TypeListLength< tListType >::length;
次、
指定したタイプリストの指定したインデックスに該当する型を取り出す方法
template < typename tList, int num >
struct TypeListAt;
template < typename H, typename T, int num >
struct TypeListAt < TypeList < H, T >, num >
{
typedef typename TypeListAt< T, num - 1 >::Result Result;
};
template < typename H, typename T >
struct TypeListAt < TypeList < H, T >, 0 >
{
typedef H Result;
};
こう定義し、次のように使う。
TypeListAt< tListType, 1 >::Result val;
こうする。先の型の登録順番からすると、上記は char val; と同義になる。
さて、ここでちょっと飛躍して、タイプリストを利用した拡散階層での実態定義をやってみる。
どういうことかというと、タイプリストに登録されている型の実態を持ったクラスを定義し、
それを最上階のタイプリストの型に多重継承して利用しようというもの。
まずは定義から、
template < typename tList, template < typename > class Unit >
class GenScatterHierarchy;
template < typename H, typename T, template < typename > class Unit >
class GenScatterHierarchy < TypeList < H, T >, Unit >
: public GenScatterHierarchy < H, Unit >,
public GenScatterHierarchy < T, Unit >
{
};
template < typename H, template < typename > class Unit >
class GenScatterHierarchy
: public Unit< H >
{
};
template < template < typename > class Unit >
class GenScatterHierarchy < NullType, Unit >
{
};
template < typename H >
struct Holder
{
H value;
};
実態となるのは、Holder型の value だ。
で、宣言の方法は次のようにする。
// まずはタイプリストを定義
typedef GenScatterHierarchy< TYPELIST_3(int, char, short), Holder > tListType;
// 次にタイプリストを実体化
tListType list;
// アクセス方法はアップキャストして行う
Holder<int>* pValue = static_cast< Holder<int>* >(&list);
pValue->value = 50;
こんな感じ。
おわり
最終更新:2008年06月19日 00:56