C++模板元编程(递归-->分解)

来源:互联网 发布:上瘾网络剧未删减全集 编辑:程序博客网 时间:2024/06/15 19:35

最近一直在看STL和Boost,源码里边好多涉及到模板元编程技术,简单了解一下,备忘(Boost Python中的涉及模板元的部分重点关注一下)。

范例引入

复制代码
// 主模板template<int N>struct Fib{    enum { Result = Fib<N-1>::Result + Fib<N-2>::Result };};// 完全特化版template <>struct Fib<1>{    enum { Result = 1 };};// 完全特化版template <>struct Fib<0>{    enum { Result = 0 };};int main(){    int i = Fib<10>::Result;    // std::cout << i << std::endl;} 
复制代码

我们将通过一个实例进行讲解,来看一下编译器实际的运作过程。我们定义了一个包含两个元素:int以及long的TypeList。


typedef TYPELIST_2(int, long) MyTypeList;


此时,编译器会根据TypeList的定义方式产生如下的类型定义结果:

struct TypeList<long, NullType>

{

typedef long H;

typedef NullType T;

};


struct TypeList<int , TypeList<long, NullType > >

{

typedef int H;

typedef TypeList<long, NullType> T;

};


在1~50的TypeList进行了预定义:

#define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>

#define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, TYPELIST_1(T2) >

#define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, TYPELIST_2(T2, T3) >

依此类推。

这样用户在使用起来就会比较方便一些。


TypeList典型操作实现

了解了TypeList的定义,这里我们将对于TypeList相关的三个典型操作(Length、TypeAt和Append)的实现进行详细的剖析。掌握了这几个典型的操作,再学习其他的操作就会变得非常的容易。


我们将通过一个实例进行讲解,来看一下编译器实际的运作过程。我们定义了一个包含两个元素:int以及long的TypeList。


typedef TYPELIST_2(int, long) MyTypeList;


此时,编译器会根据TypeList的定义方式产生如下的类型定义结果:

struct TypeList<long, NullType>

{

typedef long H;

typedef NullType T;

};


struct TypeList<int , TypeList<long, NullType > >

{

typedef int H;

typedef TypeList<long, NullType> T;

};


 

Length的实现 - 获取TypeList中的元素个数:

template <class TList> struct Length; // 仅有声明,没有实现,如果所传入的类型不是TypeLsit

// 的话,会产生一个编译期错误


template <> struct Length<NullType> // 递归调用的结束条件,NullType的大小为0,运用了

{ // 模板特化和类型萃取技

// 术

enum { value = 0 };

};


template <class T, class U> // 递归的规则定义,运用了模板偏特化和类型萃取技术

struct Length< Typelist<T, U> >

{

enum { value = 1 + Length<U>::value };

};


 

当通过Length<MyTypeList>::value获得MyTypeList中的元素个数时,看看编译器是如何根据我们指定的规则进行递归调用的。首先编译器会生成如下几个版本的Length定以:

struct Length<TypeList<long, NullType> >

{

enum { value = 1 + Length<NullType>::value };

};


struct Length<TypeList<int, TypeList<long, NullType> > >

{

enum { value = 1 + Length<TypeList<long, NullType> >::value };

};

 

根据Length结束条件的定义可知,Length<NullType>::value等于0,所以 Length<TypeList<long, NullType> >::value就等于Length<NullType>::value+1,也就是1。通过递推可 知,Length<MyTypeList>::value也就是Length<TypeList<int, TypeList<long, NullType> > >::value等于Length<TypeList<long, NullType> >::value+1,也就是2。在层层的递推过程中,类型萃取技术得到了充分的体现,value就是我们想要得到的TypeList类型相关的信 息,在每一层的递归过程中,都是通过它来保留结果的。




0 0
原创粉丝点击