1. 程式人生 > >模板超程式設計(2):計算最值

模板超程式設計(2):計算最值

   本文就Loki編譯期技術中的型別列表Typelist作了一些擴充套件,增加了以下幾個方法:
      • 獲取最大和最小長度,即求取Typelist中長度最大和最小的值  
      • 獲取最大和最小型別,即求取Typelist中長度最大和最小的型別

實現
   位於Loki::TL名稱空間,利用遞迴計算最值結果,使用巨集生成主類模板和特化類模板,其中字尾為DEFN(N為正整數)形式的巨集中N表示特化類模板所帶的模板引數數量,使用DEF1巨集定義對應的特化類模板的原因在於:當Typelist中存在非NullType型別時,保證結果的正確性。當N為2時引數取值:name為Max則b為true;name為Min則b為false。
   主類模板
   用於定義MaxSize、MinSize和MaxType、MinType主類模板,使用巨集LOKI_TYPELIST_METHOD_DEF生成。  1
#define LOKI_TYPELIST_METHOD_DEF(name)\2    template <class TList>\
3    struct name;\
4    
5    LOKI_TYPELIST_METHOD_DEF(MaxSize)
6    LOKI_TYPELIST_METHOD_DEF(MinSize)
7    LOKI_TYPELIST_METHOD_DEF(MaxType)
8    LOKI_TYPELIST_METHOD_DEF(MinType)
   最大(小)長度
   對應類主模板分別為MaxSize和MinSize,每種有3個特化模板,使用巨集LOKI_TYPELIST_SIZE_SPEC_DEFN生成(N為0、1、2)。
 1
#define LOKI_TYPELIST_SIZE_SPEC_DEF0(name)\ 2    template<>\
 3    struct name##Size<NullType>\
 4    {\
 5        enum{ value =0 };\
 6    }
;\
 7    
 8    #define LOKI_TYPELIST_SIZE_SPEC_DEF1(name)\ 9    template<class T>\
10    struct name##Size<Typelist<T,NullType>>\
11    {\
12
        enum{ value =sizeof(T) };\
13    }
;\
14    
15    #define LOKI_TYPELIST_SIZE_SPEC_DEF2(name,b)\16    template<class T,class U>\
17    struct name##Size<Typelist<T,U>>\
18    {\
19        enum{ tmp = name##Size<U>::value };\
20        enum{ value = (b ?sizeof(T) > tmp : sizeof(T) < tmp) ?sizeof(T) : tmp };\
21    }
;\
22    
23    LOKI_TYPELIST_SIZE_SPEC_DEF0(Max)
24    LOKI_TYPELIST_SIZE_SPEC_DEF0(Min)
25    LOKI_TYPELIST_SIZE_SPEC_DEF1(Max)
26    LOKI_TYPELIST_SIZE_SPEC_DEF1(Min)
27    LOKI_TYPELIST_SIZE_SPEC_DEF2(Max,true)
28    LOKI_TYPELIST_SIZE_SPEC_DEF2(Min,false)
29    
30    #undef LOKI_TYPELIST_SIZE_SPEC_DEF031    #undef LOKI_TYPELIST_SIZE_SPEC_DEF132    #undef LOKI_TYPELIST_SIZE_SPEC_DEF2
   最大(小)型別
   對應類主模板分別為MaxType和MinType,每種有3個特化模板,使用巨集LOKI_TYPELIST_TYPE_SPEC_DEFN生成(N為0、1、2)。     1#define LOKI_TYPELIST_TYPE_SPEC_DEF0(name)\ 2    template<>\
 3    struct name##Type<NullType>\
 4    {\
 5        typedef NullType type;\
 6    }
;\
 7    
 8    #define LOKI_TYPELIST_TYPE_SPEC_DEF1(name)\ 9    template<class T>\
10    struct name##Type<Typelist<T,NullType>>\
11    {\
12        typedef T type;\
13    }
;\
14    
15    #define LOKI_TYPELIST_TYPE_SPEC_DEF2(name,b)\16    template<class T,class U>\
17    struct name##Type<Typelist<T,U>>\
18    {\
19        typedef typename name##Type<U>::type R;\
20        typedef typename Select< b ? (sizeof(T)>sizeof(R)) : (sizeof(T)<sizeof(R)),T,R>::Result type;\
21    }
;\
22    
23    LOKI_TYPELIST_TYPE_SPEC_DEF0(Max)
24    LOKI_TYPELIST_TYPE_SPEC_DEF0(Min)
25    LOKI_TYPELIST_TYPE_SPEC_DEF1(Max)
26    LOKI_TYPELIST_TYPE_SPEC_DEF1(Min)
27    LOKI_TYPELIST_TYPE_SPEC_DEF2(Max,true)
28    LOKI_TYPELIST_TYPE_SPEC_DEF2(Min,false)
29    
30    #undef LOKI_TYPELIST_TYPE_SPEC_DEF031    #undef LOKI_TYPELIST_TYPE_SPEC_DEF132    #undef LOKI_TYPELIST_TYPE_SPEC_DEF2   這裡用到了Loki中的Select元件來選擇型別。

示例
使用LOKI中的LOKI_STATIC_CHECK巨集來做編譯期診斷結果正確性。
 1#define LOKI_TL4 LOKI_TYPELIST_4(double,int,short,char)  2
 3int main(int argc,char*argv[])
 4{
 5    staticconstint max_val = Loki::TL::MaxSize<LOKI_TL4 >::value;
 6    LOKI_STATIC_CHECK(max_val==sizeof(double),max_val_should_be_sizeof_double)
 7
 8    staticconstint min_val = Loki::TL::MinSize<LOKI_TL4 >::value;
 9    LOKI_STATIC_CHECK(min_val==sizeof(char),min_val_should_be_sizeof_char)
10
11    typedef Loki::TL::MaxType<LOKI_TL4 >::type max_type;
12    LOKI_STATIC_CHECK((Loki::IsSameType<max_type,double>::value),max_type_should_be_double)
13
14    typedef Loki::TL::MinType<LOKI_TL4 >::type min_type;
15    LOKI_STATIC_CHECK((Loki::IsSameType<min_type,char>::value),min_type_should_be_char)
16
17    return0;
18}
posted on 2012-05-29 01:03 春秋十二月 閱讀(1418) 評論(2)  編輯 收藏 引用 所屬分類: C/C++