Loki中的TypeList這塊是Loki中比較基礎(chǔ)的部分
其主要涉及類型鏈表(TypeList)
相關(guān)功能有
1.模板化得類型鏈表-最打提供18個(gè)類型參數(shù)
2.獲取類型鏈表的長(zhǎng)度
3.獲取給定索引位置的參數(shù)類型
4.當(dāng)索引越界時(shí)獲取設(shè)定的參數(shù)類型
5.類型鏈表的類型增加和剔除
6.其他
下面是makeTypeList的代碼
1 template
2 <
3 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
4 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
5 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
6 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
7 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
8 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
9 >
10 struct MakeTypelist
11 {
12 private:
13 typedef typename MakeTypelist
14 <
15 T2 , T3 , T4 ,
16 T5 , T6 , T7 ,
17 T8 , T9 , T10,
18 T11, T12, T13,
19 T14, T15, T16,
20 T17, T18
21 >
22 ::Result TailResult;
23
24 public:
25 typedef Typelist<T1, TailResult> Result;
26 };
27
28 template<>
29 struct MakeTypelist<>
30 {
31 typedef NullType Result;
32 };
她的作用是構(gòu)建一個(gè)模板參數(shù)不超過(guò)18個(gè)的類型鏈表
其中NullType是一種PlaceHolder
當(dāng)定義TypeList的模板參數(shù)不超過(guò)18個(gè)的時(shí)候 那么其余參數(shù)會(huì)被自動(dòng)設(shè)置為NullType
這里提供了一個(gè)泛型版本和一個(gè)特化版本
當(dāng)使用MakeTypeList<>的時(shí)候就意味著模板參數(shù)是NullTYpe
構(gòu)建除了一個(gè)類型鏈表接下來(lái)就需要獲取類型鏈表的參數(shù)個(gè)數(shù)
如下所示:
1 ////////////////////////////////////////////////////////////////////////////////
2 // class template Length
3 // Computes the length of a typelist
4 // Invocation (TList is a typelist):
5 // Length<TList>::value
6 // returns a compile-time constant containing the length of TList, not counting
7 // the end terminator (which by convention is NullType)
8 ////////////////////////////////////////////////////////////////////////////////
9
10 template <class TList> struct Length;
11 template <> struct Length<NullType>
12 {
13 enum { value = 0 };
14 };
15
16 template <class T, class U>
17 struct Length< Typelist<T, U> >
18 {
19 enum { value = 1 + Length<U>::value };
20 };
21
這里使用了典型的模板元遞歸
首先設(shè)置空的類型鏈表長(zhǎng)度為0
然后獲取指定的類型鏈表長(zhǎng)度
而TypeAt得功能是獲取類型鏈表中給定位置的元素類型
1 ////////////////////////////////////////////////////////////////////////////////
2 // class template TypeAt
3 // Finds the type at a given index in a typelist
4 // Invocation (TList is a typelist and index is a compile-time integral
5 // constant):
6 // TypeAt<TList, index>::Result
7 // returns the type in position 'index' in TList
8 // If you pass an out-of-bounds index, the result is a compile-time error
9 ////////////////////////////////////////////////////////////////////////////////
10
11 template <class TList, unsigned int index> struct TypeAt;
12
13 template <class Head, class Tail>
14 struct TypeAt<Typelist<Head, Tail>, 0>
15 {
16 typedef Head Result;
17 };
18
19 template <class Head, class Tail, unsigned int i>
20 struct TypeAt<Typelist<Head, Tail>, i>
21 {
22 typedef typename TypeAt<Tail, i - 1>::Result Result;
23 };
注意這里給定的索引不能超出類型鏈表的參數(shù)個(gè)數(shù)范圍
在這里首先給出當(dāng)索引為0時(shí)對(duì)應(yīng)的參數(shù)類型為參數(shù)鏈表中第一個(gè)元素類型(在這里就是Head)
然后獲取索引位置為i的參數(shù)類型的方法是把參數(shù)鏈表的頭位置向前退一位 這樣就可以在上一步的基礎(chǔ)上繼續(xù)調(diào)用其模板特化形式了
而模板家族TypeAtNonStrict所要做的就是在TypeAt基礎(chǔ)上所作的當(dāng)索引越界時(shí)對(duì)應(yīng)的參數(shù)類型問(wèn)題
如下所說(shuō):
1 ////////////////////////////////////////////////////////////////////////////////
2 // class template TypeAtNonStrict
3 // Finds the type at a given index in a typelist
4 // Invocations (TList is a typelist and index is a compile-time integral
5 // constant):
6 // a) TypeAt<TList, index>::Result
7 // returns the type in position 'index' in TList, or NullType if index is
8 // out-of-bounds
9 // b) TypeAt<TList, index, D>::Result
10 // returns the type in position 'index' in TList, or D if index is out-of-bounds
11 ////////////////////////////////////////////////////////////////////////////////
代碼為:
1 template <class TList, unsigned int index,
2 typename DefaultType = NullType>
3 struct TypeAtNonStrict
4 {
5 typedef DefaultType Result;
6 };
7
8 template <class Head, class Tail, typename DefaultType>
9 struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
10 {
11 typedef Head Result;
12 };
13
14 template <class Head, class Tail, unsigned int i, typename DefaultType>
15 struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
16 {
17 typedef typename
18 TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
19 };
這里有三個(gè)版本分別為獲取越界時(shí)的參數(shù)類型
獲取頭參數(shù)類型
第三個(gè)是獲取給定位置的參數(shù)類型
接下來(lái)的模板類IndexOf的作用是獲取給定類型在類型鏈表中首次出現(xiàn)的位置
1 ////////////////////////////////////////////////////////////////////////////////
2 // class template IndexOf
3 // Finds the index of a type in a typelist
4 // Invocation (TList is a typelist and T is a type):
5 // IndexOf<TList, T>::value
6 // returns the position of T in TList, or NullType if T is not found in TList
7 ////////////////////////////////////////////////////////////////////////////////
具體代碼為:
1 template <class TList, class T> struct IndexOf;
2
3 template <class T>
4 struct IndexOf<NullType, T>
5 {
6 enum { value = -1 };
7 };
8
9 template <class T, class Tail>
10 struct IndexOf<Typelist<T, Tail>, T>
11 {
12 enum { value = 0 };
13 };
14
15 template <class Head, class Tail, class T>
16 struct IndexOf<Typelist<Head, Tail>, T>
17 {
18 private:
19 enum { temp = IndexOf<Tail, T>::value };
20 public:
21 enum { value = (temp == -1 ? -1 : 1 + temp) };
22 };
需要說(shuō)明的在TypeList這里(也許更多的是在其他地方)
對(duì)這種TypeList的操作基本上都是采用的在類型鏈表基礎(chǔ)之上生成新的類型鏈表
這樣就可以保證新的參數(shù)鏈表頭結(jié)點(diǎn)為上次迭代鏈表的第2個(gè)節(jié)點(diǎn)這是這類操作的基礎(chǔ)
下面一個(gè)是對(duì)參數(shù)鏈表的參數(shù)附加
1 ////////////////////////////////////////////////////////////////////////////////
2 // class template Append
3 // Appends a type or a typelist to another
4 // Invocation (TList is a typelist and T is either a type or a typelist):
5 // Append<TList, T>::Result
6 // returns a typelist that is TList followed by T and NullType-terminated
7 ////////////////////////////////////////////////////////////////////////////////
8
9 template <class TList, class T> struct Append;
10
11 template <> struct Append<NullType, NullType>
12 {
13 typedef NullType Result;
14 };
15
16 template <class T> struct Append<NullType, T>
17 {
18 typedef Typelist<T,NullType> Result;
19 };
20
21 template <class Head, class Tail>
22 struct Append<NullType, Typelist<Head, Tail> >
23 {
24 typedef Typelist<Head, Tail> Result;
25 };
26
27 template <class Head, class Tail, class T>
28 struct Append<Typelist<Head, Tail>, T>
29 {
30 typedef Typelist<Head,
31 typename Append<Tail, T>::Result>
32 Result;
33 };
在這里可以把一個(gè)新的類型或者一個(gè)類型鏈表附加到另外一個(gè)類型鏈表中去
那么后者的參數(shù)個(gè)數(shù)數(shù)相會(huì)變?yōu)?者之和
這里的代碼表明如何把一個(gè)類型(鏈表)附加到一個(gè)NUllType上去
那么結(jié)果就是原有的類型鏈表
1 template <class T> struct Append<NullType, T>
2 {
3 typedef Typelist<T,NullType> Result;
4 };
如果附加前后的類型都為NUllType
則結(jié)果不發(fā)生變化-代碼段為第一個(gè)模板
而第三個(gè)模板表明其附加的手法是對(duì)新加入的類型鏈表中的參數(shù)類型逐個(gè)加入的
下面是相關(guān)的測(cè)試代碼:
1
2 #include <iostream>
3 #include <string>
4 #include <Loki/TypeList.h>
5
6 typedef int Type;
7 typedef Loki::TL::MakeTypelist<Type,
8 char,
9 long,
10 bool,
11 std::string,
12 double,
13 unsigned int,
14 long long> MyList;
15 class Class{};
16
17 int main()
18 {
19 MyList::Result hlist;
20 std::cout <<"MyList length "<<Loki::TL::Length<MyList::Result>::value<<std::endl;
21 Loki::TL::TypeAt<MyList::Result,1>::Result result;
22 std::cout<<"the type in indexo of 1: "<<result<<std::endl;
23 Loki::TL::TypeAtNonStrict<MyList::Result,0>::Result _type;
24 std::cout<<"default value in index of 0:" <<_type<<std::endl;
25 std::cout<<Loki::TL::IndexOf<MyList::Result,long>::value<<std::endl;
26 typedef Loki::TL::Append<MyList::Result,Class>::Result NewType;
27 std::cout <<"get length of NewType: "<< Loki::TL::Length<NewType>::value<<std::endl;
28
29 system("PAUSE");
30 return EXIT_SUCCESS;
31 }
當(dāng)然Typelist還有其他一些操作比如類型刪除等等
以后再說(shuō)吧