the boost c++ metaprogramming:boost c++ 模板元编程(2)

王朝c/c++·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

1.2.3. Type sequences

程序化的操作类型集合的能力是很多有意义的C++元程序的重要的工具

因为这种能力MPL支持的很好,这里我们仅仅简要的介绍一下基础的东西

后面,我们将重新回顾下面的例子,并演示如何使用MPL来实现

首先,我们需要一种方法来表示这个容器;一个主意是用structure来存储类型:

struct types

{

int t1;

long t2;

std::vector<double> t3;

};

不幸的是,这种安排无法使用C++给我们的编译期类型内省的能力(类似Java的Reflection)

没有办法找出成员的名字是什么,即使我们假定名字是按照上面的惯用法给出的,我们也没有办法知道有多少个成员;解决这个问题的关键是提高表示的一致性;如果我们有一个方法可以得到任何序列的第一个类型,和剩余的序列,那么我们将轻易的获取所有成员:

template< typename First, typename Rest >

struct cons

{

typedef First first;

typedef Rest rest;

};

struct nil {};

typedef

cons<int

, cons<long

, cons<std::vector<double>

, nil

> > > my_types;

上面的my_types所描述的结构是单向链表的编译期对应物,是由Czarnecki and Eisenecker in [CE98]首先引进的;现在,我们已经调整了最初的结构,此时C++模板机制能够一层层的剥开它,我们来看一个完成这个功能的简单的metafunction;假设用户希望找到任意类型集合中最大的一个类型;我们可以使用现在已经很熟悉的递归的metafunction:

Example 1. 'largest' metafunction

// choose the larger of two types

template<

typename T1

, typename T2

, bool choose1 = (sizeof(T1) > sizeof(T2)) // hands off!

>

struct choose_larger

{

typedef T1 type;

};

// specialization for the case where sizeof(T2) >= sizeof(T1)

template< typename T1, typename T2 >

struct choose_larger< T1,T2,false >

{

typedef T2 type;

};

// get the largest of a cons-list

template< typename T > struct largest;

// specialization to peel apart the cons list

template< typename First, typename Rest >

struct largest< cons<First,Rest> >

: choose_larger< First, typename largest<Rest>::type >

{

// type inherited from base

};

// specialization for loop termination

template< typename First >

struct largest< cons<First,nil> >

{

typedef First type;

};

int main()

{

// print the name of the largest of my_types

std::cout

<< typeid(largest<my_types>::type).name()

<< std::endl

;

}

这段代码中有几个地方值得注意:

• 它使用了一些ad-hoc,深奥的技术,或者“hacks”

缺省模板参数choose1(用“hands off!”做了标记)就是一个例子;没有它,我们将需要另外一个模板来提供choose_larger的实现,或者我们不得不显式的计算后作为参数提供给模板,对这个例子也许不算太坏,但它将使choose_larger用处更少,更加容易出错

另一个hack是从choose_larger中分出特化的largest;这是一种减少代码的措施,将使程序员避免在模板体中编写“typedef typename ...::type type”等

• 即使这么简单的元程序也使用了三个单独的偏特化

largest metafunction使用了两个特化;有人可能期待着这意味着有两个结束条件,但不是这样的:其中一个特化只是用来简单的处理对序列元素的存取;这些特化通过将单个metafunction的定义散布在几个C++模板的定义中而使代码难以阅读;并且,因为它们是偏特化,对于C++社区中其编译器不支持偏特化的广大的程序员来说,它们是不可用的

然而,这些技术理所当然是任何好的C++元程序员武器库中很有价值的部分;通过封装常用的结构,内部处理循环结束,MPL减少了tricky hacks和模板特化的需要

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航