模板超程式設計(2):計算最值
阿新 • • 發佈:2018-12-27
本文就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++
• 獲取最大和最小長度,即求取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
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
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
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++