關於 C++ 泛型中的 TypeTraits ,參考 c++ 泛型編程 之 TypeTraits
#ifndef TYPE_LISTS_H_ #define TYPE_LISTS_H_ #include#include #include typetraits.h /* TypeLists 內部沒有任何數值(value),他們的實體是空的,不含有任何狀態,也未定義任何函數。 執行期間TypeLists也不帶任何數值,他們存在的理由只是為了攜帶型別信息。TypeLists 並未打算被具 現化。因此,當我們說“a TypeListL”,實際指的是一個typelist型別,不是一個typelist 對象。 規定 typelist 必須以NullType(類)結尾,NullType可被視為一個結束符號,類似於c字符串的功能, 定義一個只有一個元素的typelist如下: typedef Typelist OneTypeOnly. */ template struct Typelist { typedef T Head; typedef U Tail; }; //通過定義宏 將typelist線性化 #define TYPELIST_0() NullType #define TYPELIST_1(T1) Typelist #define TYPELIST_2(T1,T2) Typelist #define TYPELIST_3(T1,T2,T3) Typelist #define TYPELIST_4(T1,T2,T3,T4) Typelist #define TYPELIST_5(T1,T2,T3,T4,T5) Typelist //計算TypeList長度 //大多數Typelist的操作都是基於遞歸,遞歸終止條件通過模板特化實現。 template struct Length; template<>struct Length //Length的全特化,即,只匹配NullType。 { enum{value = 0}; }; template struct Length >//Length的扁特化,可匹配任何TypeList 類型,包括U同時也是Typelist的復合情況。 { enum{value = 1+Length::value}; }; //2 索引式訪問 template struct TypeAt; template struct TypeAt ,0> { typedef Head Result; }; template struct TypeAt ,i> { typedef typename TypeAt ::Result Result; }; //類似TypeAt功能,不過TypeAtNonStrict對逾界訪問更加寬容。 //比如TypeList的個數是3,那麼你不能使用TypeAt ::Result,這樣會編譯錯誤。 //但是TypeAtNonStrict ::Result可以,如果不存在索引為3的type,那麼結果是第三個引數即NullType template struct TypeAtNonStrict { typedef DefType Result; }; template struct TypeAtNonStrict< Typelist , 0, DefType > { typedef T Result; }; template struct TypeAtNonStrict< Typelist , i, DefType > { typedef typename TypeAtNonStrict::Result Result; }; //3 查找TypeList template struct IndexOf;//聲明 template struct IndexOf //如果TList為NullType,那麼令value = -1; { enum{value = -1}; }; template struct IndexOf ,T>//如果T是TList中的頭端,那麼令value= 0; { enum{value = 0}; }; template //將IndexOf施於TList尾端和T,並將結果置於一個臨時變量temp struct IndexOf ,T>//如果temp為-1,令value為-1,否則令value為1+temp { private: enum{temp = IndexOf ::value};//temp要先於value聲明定義。 public: enum{value = temp == -1 ? -1 : temp + 1}; }; //4 附加元素到typelist template struct Append;//聲明 template<>struct Append //如果TList是NULL而且T是NULL,那麼令Result為NullType { typedef NullType Result; }; template struct Append //如果TList是NullType,且T是type(非typelist), { //那麼Result將是只含有唯一元素的T; typedef TYPELIST_1(T) Result; }; template struct Append >// 如果TList是NullType,且T是一個typelist,那麼Result便是T本身 { typedef Typelist Result; }; template //否則,如果Tlist是non-null,那麼result將是個typelist,以TList::Head struct Append ,T> //為起頭端,並以T附加到TList::Tail的結果為其尾端。 { typedef Typelist::Result> Result; }; //5 Reverse template struct Reverse; template <>struct Reverse { typedef NullType Result; }; template struct Reverse< Typelist > { typedef typename Append< typename Reverse ::Result, Head>::Result Result; }; #endif
測試
void typelists_test()
{
typedef TYPELIST_0() TL0;
typedef TYPELIST_3(char,int,double) TL3;
typedef TYPELIST_3(char,int,double) TL3_1;
//Length
std::cout<::value<::value<::Result Parm1;
typedef TypeAt::Result Parm2;
typedef TypeAt::Result Parm3;
typedef TypeAtNonStrict::Result TEST_TYPE;
std::cout<::value<::value<::value< TL4;//TL4不是一個TypeList
typedef Append TL5;
std::cout<::value<::value<::Result).name()<