接上文
下面看看TypeList的类型删除功能
相关源码为:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////
// class template Erase
// Erases the first occurence, if any, of a type in a typelist
// Invocation (TList is a typelist and T is a type):
// Erase<TList, T>::Result
// returns a typelist that is TList without the first occurence of T
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**/////////////////////////////////////////////////////////////////////////////////![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template <class TList, class T> struct Erase;
template <class T> // Specialization 1
struct Erase<NullType, T>
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
typedef NullType Result;
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template <class T, class Tail> // Specialization 2
struct Erase<Typelist<T, Tail>, T>
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
typedef Tail Result;
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template <class Head, class Tail, class T> // Specialization 3
struct Erase<Typelist<Head, Tail>, T>
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
typedef Typelist<Head,
typename Erase<Tail, T>::Result>
Result;
};
正如所说
Erase删除的类型是第一次出现的类型
其特化版本有3个第一个是针对空类型链表的删除
其二和其三的相互迭代构成了对所有位置类型的删除动作
TypeList的下一个操作是对链表的给定类型清空动作
////////////////////////////////////////////////////////////////////////////////
// class template EraseAll
// Erases all first occurences, if any, of a type in a typelist
// Invocation (TList is a typelist and T is a type):
// EraseAll<TList, T>::Result
// returns a typelist that is TList without any occurence of T
////////////////////////////////////////////////////////////////////////////////
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;
};
接着,下面的代码实现的功能分别是
1.删除类型链表中所有重复的类型
2.类型替换的解决
1.删除类型链表中重复的类型
代码为:
////////////////////////////////////////////////////////////////////////////////
// class template NoDuplicates
// Removes all duplicate types in a typelist
// Invocation (TList is a typelist):
// NoDuplicates<TList, T>::Result
////////////////////////////////////////////////////////////////////////////////
template <class TList> struct NoDuplicates;
template <> struct NoDuplicates<NullType>
{
typedef NullType Result;
};
template <class Head, class Tail>
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;
};
如果链表为空则不操作
如果链表为非空则进行以下动作
删除位置位置为1,2,3,..的重复类型
下面的功能则是类型替换和链表翻转
////////////////////////////////////////////////////////////////////////////////
// class template Replace
// Replaces the first occurence of a type in a typelist, with another type
// Invocation (TList is a typelist, T, U are types):
// Replace<TList, T, U>::Result
// returns a typelist in which the first occurence of T is replaced with U
////////////////////////////////////////////////////////////////////////////////
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;
};
////////////////////////////////////////////////////////////////////////////////
// class template ReplaceAll
// Replaces all occurences of a type in a typelist, with another type
// Invocation (TList is a typelist, T, U are types):
// Replace<TList, T, U>::Result
// returns a typelist in which all occurences of T is replaced with U
////////////////////////////////////////////////////////////////////////////////
template <class TList, class T, class U> struct ReplaceAll;
template <class T, class U>
struct ReplaceAll<NullType, T, U>
{
typedef NullType Result;
};
template <class T, class Tail, class U>
struct ReplaceAll<Typelist<T, Tail>, T, U>
{
typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
};
template <class Head, class Tail, class T, class U>
struct ReplaceAll<Typelist<Head, Tail>, T, U>
{
typedef Typelist<Head,
typename ReplaceAll<Tail, T, U>::Result>
Result;
};
////////////////////////////////////////////////////////////////////////////////
// class template Reverse
// Reverses a typelist
// Invocation (TList is a typelist):
// Reverse<TList>::Result
// returns a typelist that is TList reversed
////////////////////////////////////////////////////////////////////////////////
template <class TList> struct Reverse;
template <>
struct Reverse<NullType>
{
typedef NullType Result;
};
template <class Head, class Tail>
struct Reverse< Typelist<Head, Tail> >
{
typedef typename Append<
typename Reverse<Tail>::Result, Head>::Result Result;
};
类型链表的最后一个设计的功能是鉴别类型链表中有多少个类型继承于给定类型
////////////////////////////////////////////////////////////////////////////////
// class template MostDerived
// Finds the type in a typelist that is the most derived from a given type
// Invocation (TList is a typelist, T is a type):
// MostDerived<TList, T>::Result
// returns the type in TList that's the most derived from T
////////////////////////////////////////////////////////////////////////////////
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;
};
////////////////////////////////////////////////////////////////////////////////
// class template DerivedToFront
// Arranges the types in a typelist so that the most derived types appear first
// Invocation (TList is a typelist):
// DerivedToFront<TList>::Result
// returns the reordered TList
////////////////////////////////////////////////////////////////////////////////
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是排列类型链表保持后面的类型继承于前面的类型
全文测试代码如下:
#include <iostream>
#include <string>
#include <Loki/TypeList.h>
#include <typeinfo>
typedef int Type;
typedef Loki::TL::MakeTypelist<Type,
char,
long,
bool,
int,
std::string,
double,
unsigned int,
long long,
int> MyList;
class Class{};
class Class1: public Class{};
class Class2: public Class{};
class Class3: public Class{};
int main()
{
MyList::Result hlist;
std::cout <<"MyList length "<<Loki::TL::Length<MyList::Result>::value<<std::endl;
Loki::TL::TypeAt<MyList::Result,1>::Result result;
std::cout<<"the type in indexo of 1: "<<result<<std::endl;
Loki::TL::TypeAtNonStrict<MyList::Result,0>::Result _type;
std::cout<<"default value in index of 0:" <<_type<<std::endl;
std::cout<<Loki::TL::IndexOf<MyList::Result,long>::value<<std::endl;
typedef Loki::TL::Append<MyList::Result,Class>::Result NewType;
std::cout <<"get length of NewType: "<< Loki::TL::Length<NewType>::value<<std::endl;
typedef Loki::TL::Erase<MyList::Result,double>::Result NewType2;
std::cout<<"new length of NewType:"<<Loki::TL::Length<NewType2>::value<<std::endl;
typedef Loki::TL::EraseAll<MyList::Result,int>::Result NewType3;
std::cout<<"new length of NewType after erase all int type:"<<Loki::TL::Length<NewType3>::value<<std::endl;
typedef Loki::TL::NoDuplicates<MyList::Result>::Result NewType4;
std::cout<<"new length of New type after NoDuplicates "<<Loki::TL::Length<NewType4>::value<<std::endl;
typedef Loki::TL::Replace<MyList::Result,int,Class>::Result NewType5;
typedef Loki::TL::Append<MyList::Result,Class1>::Result NewType6;
typedef Loki::TL::Append<MyList::Result,Class2>::Result NewType7;
typedef Loki::TL::Append<MyList::Result,Class3>::Result NewType8;
typedef Loki::TL::Append<MyList::Result,Class2>::Result NewType9;
typedef Loki::TL::Append<MyList::Result,long>::Result NewType10;
Loki::TL::MostDerived<NewType10,int>::Result r;
std::cout<<typeid(Loki::TL::MostDerived<NewType10,Class>::Result).name()<<std::endl;
Loki::TL::DerivedToFront<NewType10>::Result t;
std::cout<<"new length of New type after Arrange TypeList "<<Loki::TL::Length<NewType10>::value<<std::endl;
int len = Loki::TL::Length<NewType10>::value;
std::cout<<"the type name in given lindex : "<<typeid(Loki::TL::TypeAtNonStrict<MyList::Result,11>::Result).name()<<std::endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Loki TypeList写完了
感觉到了模板元编程的强大之处