【C++泛型编程】Typelists型别工具
分类: C/C++、STL、泛型编程2012-09-04 15:28 321人阅读 评论(0) 收藏 举报 c++编程classstruct算法float http://blog.csdn.net/xiaoding133/article/details/7935309Typelists是一个用来操作一大群型别的C++工具,就像lists对数值提供各种基本操作一样。
1.定义Typelists
Typelist是以一种特殊的型别结束:NullType
- class NullType {};
- struct EmptyType {}; // could be instantiated
- template <class T, class U>
- struct Typelist
- {
- typedef T Head;
- typedef U Tail;
- };
下面我们可以定义以NullType结束的型别,每个typelist都必须以NullType结尾。NullType可以视为一个结束记号,类似'\0'的功能。
typedef Typelist< char, Typelist<signed char,
Typelist<unsigned char, NullType> > > Charlist;
注:Typelists内部没有任何数值:他们的实体是空的,不含任何的状态,也未定义任何的函数。执行期间typelists也不带任何数值。它们存在的理由只是为了携带型别信息。因此,对typelist的任何处理都一定发生在编译期而不是执行期。
2.将Typelist的生成线性化
用宏来将递归形式转化成比较简单的枚举形式,取代比较冗长的的重复动作。Loki把Typelists的长度扩充到了50.
- #define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
- #define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, LOKI_TYPELIST_1(T2) >
- #define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, LOKI_TYPELIST_2(T2, T3) >
- #define TYPELIST_4(T1, T2, T3, T4) \
- ::Loki::Typelist<T1, LOKI_TYPELIST_3(T2, T3, T4) >
现在可以用简单的方式定义Charlist了
typedef TYPELIST_3(char, signed char, unsigned char) Charlist;
3.计算长度
假设TList typelist,它有一个编译期常数代表其长度。因为typelists是一种静态构件,所以这个与typelists相关的计算在编译期完成。计算typelist长度的代码如下:
- //
- // 长度
- //
- template <class TList> struct Length;
- template <>
- struct Length<NullType> //Length的全特化,只匹配NullType
- {
- enum { value = 0 };
- };
- template <class T, class U>
- struct Length <Typelist<T,U> > //Length的偏特化,可以匹配任何Typelist<T,U>型别,包括复合型
- {
- enum { value = 1 + Length<U>::value };
- };
4.索引访问
一个带有索引操作的template的声明式如下:
template<class TList,unsigned int index>struct TypeAt;
TypeAt:
输入:typelist TList,索引值i
输出:内部某型别Result
如果TList不为null且i=0,那么Result就是TList的头部
否则
如果TList不为null且i不为0,那么Result就是将TypeAt施行于TList尾端及i-1的结果
否则越界访问,造成编译错误。
TypeAt的算法如下:
- template <class Head, class Tail>
- struct TypeAt< TypeList<Head, Tail>, 0>
- {
- typedef Head Result;
- };
- template <class Head, class Tail, unsigned int i>
- struct TypeAt< TypeList<Head, Tail, i>
- {
- typedef typename TypeAt<Tail,i-1>::Result Result;
- };
5.查找Typelists
流程如下:
if TList is NullType then -1
if the Head is T then 0
if IndexOf(Tail,T)==-1 then -1
else IndexOf(Tail,T)+1
算法如下:
- template <class TList, class T> struct IndexOf;
- template <class T>
- struct IndexOf< NullType, T>
- {
- enum { value = -1 };
- };
- template <class T, class Tail>
- struct IndexOf< Typelist<Head, Tail>, T>
- {
- private:
- enum { temp = IndexOf<Tail, T>::value };
- public:
- enum { value = (temp == -1) ? -1 : 1+temp };
- };
6.附加元素到Typelist
- //
- // Append
- //
- template <class TList, class T> struct Append;
- template <>
- struct Append< NullType, NullType>
- {
- typedef NullType Result;
- };
- template <class T>
- struct Append< NullType, T>
- {
- typedef TYPELIST_1(T) Result;
- };
- template <class Head, class Tail>
- struct Append< NullType, Typelist<Head,Tail> >
- {
- tyepdef Typelist<Head,Tail> Result;
- };
- template <class Head, class Tail, class T>
- struct Append< Typelist<Head,Tail>, T>
- {
- typedef Typelist<Head, typename Append<Tail,T>::Result> Result;
- };
使用方法如下:
typedef Append<SignedIntegrals,
TYPELIST_3(float,double,long double)>::Result SignedTypes;
7.移除Typelist中的某个元素
- //
- // Erase
- //
- template <class TList, class T> struct Erase;
- template <class T>
- struct Erase< NullType, T>
- {
- typedef NullType Result;
- };
- template <class T, clas Tail>
- struct Erase< Typelist<T, Tail>, T>
- {
- typedef Tail Result;
- };
- template <class Head, class Tail, class T>
- struct Erase< TypeList<Head, Tail>, T>
- {
- typedef TypeList<Head, typename Erase<Tail,T>::Result> Result;
- };
使用方法:
typedef Erase<SignedTypes,float>::Result SomeSignedTypes;
移除所有的元素:
- template <class TList, class T> struct EraseAll;
- template <class T>
- struct EraseAll<NullType, T>
- {
- typedef NullType Result;
- };
- template <class T, class Tail>
- struct EraseAll<Typelist<T, Tail>, T>
- {
- // Go all the way down the list removing the type
- typedef typename EraseAll<Tail, T>::Result Result;
- };
- template <class Head, class Tail, class T>
- struct EraseAll<Typelist<Head, Tail>, T>
- {
- // Go all the way down the list removing the type
- typedef Typelist<Head,
- typename EraseAll<Tail, T>::Result>
- Result;
- };
8.移除重复的元素
- template <class TList> struct NoDuplicates;
- template <> struct NoDuplicates<NullType>
- {
- typedef NullType Result;
- };
- template <class Head, class
- struct NoDuplicates< Typelist<Head, Tail> >
- {
- private:
- typedef typename NoDuplicates<Tail>::Result L1;
- typedef typename Erase<L1, Head>::Result L2;
- public:
- typedef Typelist<Head, L2> Result;
- };
9.取代Typelist中的某个元素(以型别U取代型别T)
- template <class TList, class T, class U> struct Replace;
- template <class T, class U>
- struct Replace<NullType, T, U>
- {
- typedef NullType Result;
- };
- template <class T, class Tail, class U>
- struct Replace<Typelist<T, Tail>, T, U>
- {
- typedef Typelist<U, Tail> Result;
- };
- template <class Head, class Tail, class T, class U>
- struct Replace<Typelist<Head, Tail>, T, U>
- {
- typedef Typelist<Head,
- typename Replace<Tail, T, U>::Result>
- Result;
- };
10. 为Typelists局部更换次序
让派生型别出现在基础型别之前。MostDerived算法接受一个typelist和一个Base型别,传回typelist中base的最深层派生型别。如果找不到任何派生型别,就返回Base自己。
如下:
- template <class TList, class T> struct MostDerived;
- template <class T>
- struct MostDerived<NullType, T>
- {
- typedef T Result;
- };
- 、
- template <class Head, class Tail, class T>
- struct MostDerived<Typelist<Head, Tail>, T>
- {
- private:
- typedef typename MostDerived<Tail, T>::Result Candidate;
- public:
- typedef typename Select<
- SuperSubclass<Candidate,Head>::value,
- Head, Candidate>::Result Result;
- };
DerivedToFront算法是以MostDerivedwei为基础,如下:
- template <class TList> struct DerivedToFront;
- template <>
- struct DerivedToFront<NullType>
- {
- typedef NullType Result;
- };
- template <class Head, class Tail>
- struct DerivedToFront< Typelist<Head, Tail> >
- {
- private:
- typedef typename MostDerived<Tail, Head>::Result
- TheMostDerived;
- typedef typename Replace<Tail,
- TheMostDerived, Head>::Result Temp;
- typedef typename DerivedToFront<Temp>::Result L;
- public:
- typedef Typelist<TheMostDerived, L> Result;
- };
DerivedToFront转换可以高效的将“型别处理工序”自动化。