`
zhangyafei_kimi
  • 浏览: 265512 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

C++ Meta Programming 和 Boost MPL(4)

阅读更多

本系列全部转载自kuibyshev.bokee.com

1. Boost中的MPL库分析

MPL是由David AbrahamsAleksey Gurtovoy为方便模板元编程而开发的库,2003年被Boost吸纳为其中的一员,此后又历经一些大幅度修改,目前已经相当完善,其最新版本于200411月发布。MPL的出现是C++模板元编程发展中的一大创举,它提供了一个通用、高层次的编程框架,其中包括了序列(Sequence)、迭代器(Iterator)、算法(Algorithm)、元函数(Metafunction)等多种组件,具有高度的可重用性,不但提高了模板元编程的效率,而且使模板元编程的应用范围得到相当的扩展。

1.1. MPL的组织架构

一个库的组织形式有时候甚至比它的功能还重要。MPL的作者聪明地借鉴了已经取得巨大成功的STL,在MPL中保留了许多STL的概念,对函数式的编程方式进行了精巧的包装,使得任何熟悉STL的程序员都可以轻易地理解MPL的使用方法。像STL一样,MPL有一个完整的概念体系,对组件作了精心的划分,组件之间相对独立,接口具有通用性,因此将组件之间的依存度和耦合性降低到最小的限度。

STLMPL的组件概念对照如下:

STL概念

MPL对应概念

容器(Container

序列(Sequence

算法(Algorithm

算法(Algorithm

迭代器(Iterator

迭代器(Iterator

仿函数(Functor

元函数类(Metafunction

配接器(Adaptor

ViewInserter Iterator和相当于仿函数配接器的Binding元函数

配置器(Allocator

无此概念

标准中没有定义

宏(Macro

1.2. MPL对其他库的依赖

MPL是一个高层次的库,它的地位和编译期执行的特殊性决定了它需要一些特殊的辅助设施,并对其他库会有所依赖。

1.2.1. BoostPreprocessor

Preprocessor库是一个基于宏的元编程库[7]。预处理器的作用发生在编译以前,所以它比MPL所处的地位还要高端,能够真正实现代码生成。它的典型功能是迭代或者枚举相似的代码段,减少重复而易写错的代码段。MPL中不少代码是近似的,比如在vector的原始代码中,就需要定义n

vectori { … }

其中i1迭代到n。为了减少重复劳动,MPL的源代码大量使用自定义和Preprocessor库的宏对重复或具有递推性的内容进行迭代。不过,这也导致源代码难以阅读。比如上面一段展开后的源代码首先是定义在vector/aux_/numbered.cpp的:

// Preprocessor的宏,得到目前属于第几次迭代

#define i_ BOOST_PP_FRAME_ITERATION(1)

...

template<

//Preprocessor的宏,枚举参数列表

BOOST_PP_ENUM_PARAMS(i_, typename T)

>

// Preprocessor的宏,拼合vector和当前次数

struct BOOST_PP_CAT(vector,i_)

{ ... }

然后为了迭代n个上面的类模板,另一个文件则需要重复include这个文件,利用Preprocessor的文件迭代能力可以这样写:

// Preprocessor的宏,其中第一个参数3表示后面的参数组有3

//元素,010表示迭代的范围是从010,最后一个参数是文件

//迭代的文件名

# define BOOST_PP_ITERATION_PARAMS_1 \

(3,(0, 10, ))

// Preprocessor的宏,要求按照上面的指定的参数进行递归

# include BOOST_PP_ITERATE()

尽管如此,宏还是必需的,它不但避免了重复编写递推式的代码(比如在上述的vector类模板中,n可达50之大,如果完全手写确实是浪费时间),而且还有效控制了代码的生成(比如只需要通过定义迭代次数,即可控制实际生成的类模板个数)。实际上,在使用vector(或其他组件)时,通常我们并不需要每次编译都把这些代码重新生成一次,MPL的作者已经充分考虑到编译效率的问题,所以在MPL的代码中,为每个流行的编译器都建立了一个Processed目录,里面存放着针对编译器特点展开了的代码。仅当定义了BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS时才会强制MPL重新用宏来生成代码。

MPL的作者指出,无论喜欢还是不喜欢,目前宏必须在MPL中扮演着这个不可替代的角色。

1.2.2. BoostType Traits

Type Traits[9]用于验证传递的参数或参数之间是否符合一定的条件,比如可以判定两个参数是否有继承关系、是否可转换等。

1.2.3. BoostStatic Assert

Static Assert[8]用于编译时断言,用法类似于C中常用的断言assert()。如果参数经编译时的静态计算为true,则代码能通过编译,不会有任何效果,反之,则会编译出错,并且在使编译信息里面包含有“STATIC_ASSERTION_FAILURE”的字样。

Static Assert的底层是接受一个bool参数的模板STATIC_ASSERTION_FAILURE,它对true定义一个有成员的特化模板,对false的情况则只有一个特化的声明(无定义)。其接口是一个宏,它产生的代码是sizeof(STATIC_ASSERTION_FAILURE< ... >),显然当参数的实际结果为false时,编译器无法判断STATIC_ASSERTION_FAILURE的长度,因为它尚未定义。

因为MPL是只在编译时生效的库,用Static Assert来调试程序是非常合适的,它往往与Type Traits库搭配使用。

1.2.4. BoostConfig

STL一样,由于编译器对标准支持不同,为了使程序库具有移植性,最好是针对环境进行预先的设置。对于MPL这种先锋性的库来说,编译器问题更加让库作者相当头痛。借助于对环境的侦查,可以对预先发现的问题,比如模板的局部特化能力、已知的一些编译器的bug等等,采取相应的补救措施[4]

1.3. MPL中的序列

1.3.1. MPL序列概述

序列是MPL中的数据结构的统称,是MPL中处于中心地位的组件,其地位相当于STL中的容器。MPL对序列的性质进行了细致的划分:

性质

含义 / 主要模型

前向序列Forward Sequence

beginend元函数能够界定其头尾范围的类型序列 / MPL中所有序列

双向序列Bidirectional Sequence

迭代器属于双向迭代器的前向序列 / vectorrange_c

随机访问序列Random Access Sequence

迭代器属于随机访问迭代器的双向序列 / vectorrange_c

可扩展序列Extensible Sequence

允许插入和删除元素的序列 / vectorlist

前可扩展序列Front Extensible Sequence

允许在前端插入和删除元素的可扩展序列 / vectorlist

后可扩展序列Back Extensible Sequence

允许在后端插入和删除元素的可扩展序列 / vectorlist

关联序列Associative Sequence

可以用key值来检索元素的前向序列 / setmap

可扩展关联序列Extensible Associative Sequence

允许插入和删除元素的关联序列 / setmap

整型序列包装器Integral Sequence Wrapper

存放一系列整型常量类(Integral Constant)的一种类模板 / vector_clist_cset_c

不定序列Variadic Sequence

可以用给定元素个数或用不指定元素个数的形式来定义的序列 / vectorlistmap

部分概念在现阶段的MPL版本中其实存在着一些冗余,但这种以概念驱动的程序库却是很清晰的:每一种概念的背后都指明了它所支持的操作。

1.3.2. vectordeque

1)概述

MPL中最简单和最常用的序列就是vector。而deque在目前版本的MPL中相当于vectorvector的实质十分类似于前面示例的类型数组,逻辑上是连续线性的,由于它属于不定序列,使用时既可以指定长度,以vectornn>来定义,也可以直接用vectorn>来定义。注意n不能超过宏BOOST_MPL_LIMIT_VECTOR_SIZE的定义,目前MPL的默认值是20vector的特点是支持尾端常数时间的插入和删除操作以及中段和前端线性时间的插入和删除操作。

2)操作

vector支持的操作无论在命名还是逻辑上基本都与STL 一致,但有一个重大区别,STL的操作函数定义在类的内部,但是限于模板元编程的特殊性,MPL的这些元函数在容器外定义。下表列出它们的用法:

begin::type

返回一个迭代器指向v的头部

end::type

返回一个迭代器指向v的尾部

size::type

返回一个v的大小

empty::type

当且仅当v为空时返回一个整型常量类,其值为true

front::type

返回v的第一个元素

back::type

返回v的最后一个元素

at::type

返回v的第n个元素

insert::type

返回一个新的vector使其定义为[begin::type, pos), x, [pos, end::type)

insert_range::type

返回一个新的vector使其定义为[begin::type, pos), [begin::type, end::type) [pos, end::type)

erase::type

返回一个新的vector使其定义为[begin::type, pos), [next::type, end::type)

erase::type

返回一个新的vector使其定义为[begin::type, pos), [last, end::type)

clear::type

返回一个空的vector

push_back::type

返回一个新的vector使其定义为[begin::type, end::type), x

pop_back::type

返回一个新的vector使其定义为[begin::type, prior< end::type >::type)

push_front::typ

分享到:
评论

相关推荐

    C++ Metaprogramming 和 Boost MPL

    Boost库中的MPL(Meta-Programming Library)是一个专门为模板元编程设计的库,它包含了许多创新性的概念,如类型序列、算法和表达式模板,极大地扩展了C++模板的功能。 C++元编程的核心是模板,模板不仅用于生成...

    c++最新技术 BOOST

    在泛型编程方面,书中会讲解BOOST.MPL(Meta Programming Library),这是一个强大的元编程库,允许在编译时进行计算和类型操作,这对于创建高效且高度定制化的模板类和函数至关重要。另外,BOOST.Fusion提供了用于...

    C++使用的boost库

    Boost.MPL(Meta-Programming Library)和Boost.TypeTraits库提供了编译时元编程工具,允许开发者在编译期间进行类型检查和计算。 Boost库的设计理念是提高C++的可移植性、效率和可维护性。通过使用Boost库,...

    C++参考手册中文版chm以及Boost库中文版chm

    6. **模式匹配和元编程**:例如 MPL(Meta-Programming Library)允许在编译时进行计算。 7. **序列化**:提供将数据结构序列化到文件或内存流的能力,便于持久化存储。 8. **正则表达式**:实现了标准C++库尚未...

    c++boost库最新版本

    3. **模板元编程**:Boost.MPL(Meta-Programming Library)允许在编译时进行计算,提高了代码的效率和灵活性,是C++模板元编程的重要工具。 4. **正则表达式**:Boost.Regex库提供了符合POSIX标准的正则表达式操作...

    C++0x实现类似于mpl的一个类型容器

    本项目旨在利用C++0x的可变模板参数来实现一个类似于Boost MPL(Meta Programming Library)的类型容器。Boost MPL是一个元编程库,它提供了一种在编译时处理类型和数值的方法,是C++模板元编程的重要工具。 首先,...

    Beyond+the+C+++Standard+Library(boost中文版).rar

    2. **模板元编程**:Boost.MPL(Meta-Programming Library)是一个强大的模板元编程库,允许在编译时执行计算,极大地提高了代码的效率。 3. **智能指针**:Boost库中的智能指针,如Boost.SmartPtr,可以有效地管理...

    Boost程序库探秘——深度解析C++准标准库

    模板元编程是Boost库的另一大亮点,如Boost.MPL(Meta-Programming Library)提供了丰富的元函数和元操作,使得程序员可以在编译时进行计算。这对于构建高效、类型安全的代码至关重要。 在并发处理方面,Boost库...

    超越c++标准库——boost程序库导论.rar

    3. **模板元编程**:Boost.MPL(Meta-Programming Library)提供了一种在编译时进行计算和操作的方式,增强了C++模板的功能,使开发者能够在编译期进行更复杂的类型操作。 4. **并发与多线程**:Boost.Thread库提供...

    The Boost C++ Libraries 中文版 chm

    例如,`Boost.MPL`(Meta-Programming Library)提供了丰富的元函数和容器,实现编译时的泛型编程。 3. **智能指针**:Boost库提供了多种智能指针,如`shared_ptr`、`unique_ptr`和`weak_ptr`,它们在内存管理上比...

    boost c++ application development cookbook 2nd

    1. **模板元编程**:Boost.MPL(Meta-Programming Library)允许开发者在编译时执行计算,创建类型列表,实现强大的类型系统操作。 2. **智能指针**:Boost.Smart_ptr包括shared_ptr、unique_ptr和weak_ptr,提供了...

    超越C++标准库-boost程序库导论

    - **Boost.MPL**(Meta Programming Library):支持元编程,即在编译时进行计算。 - **Boost.Fusion**:用于组合和操作不同类型的数据结构。 - **Boost.TypeTraits**:提供了对类型信息的操作能力。 - **Boost....

    C++ boost源文件

    - **泛型编程**: Boost MPL(Meta-Programming Library)和Boost.Fusion提供元编程和类型序列处理工具,是模板元编程的强大工具。 4. **智能指针的应用场景** - **内存管理**: 智能指针可以自动管理内存,防止...

    Boost C++ Application Development Cookbook 源代码

    例如,Boost.TypeTraits库提供了许多工具来查询类型属性,而Boost MPL(Meta Programming Library)则提供了一套完整的元编程框架。 3. **智能指针**:Boost库中的smart_ptr(包括shared_ptr、unique_ptr、weak_ptr...

    Boost C++ 库文档合集

    Boost库中包含了许多用于模板元编程的工具,如`mpl`(Meta-programming Library)和`fusion`,它们可以帮助开发者创建更高效、更类型安全的代码。 2. **标准模板库(Standard Template Library, STL)** STL是C++...

    Boost程序库完全开发指南

    10. **元编程**(Meta-Programming):Boost.MPL(Metaprogramming Library)和Boost.TypeTraits是元编程的重要工具,它们允许在编译时执行计算和检查类型属性。 11. **模板元编程**(Template Meta-Programming)...

    Boost程序库完全开发指南_深入Cpp.准标准库及库详解

    Boost.MPL(Meta-Programming Library)是一个强大的模板元编程库,允许程序员在编译时执行计算和创建类型。 此外,Boost还包含了对智能指针(如BoostSharedPtr和BoostUniquePtr)、函数对象绑定(Boost.Bind和...

    (C++元编程)C++ Template Metaprogramming Concepts, Tools, and Techniques from Boost and Beyond.chm

    4. **Boost库中的元编程工具**:Boost库提供了丰富的元编程工具,如Type Traits、 MPL(Meta Programming Library)、Preprocessor等,这些工具可以帮助开发者编写出更加高效和强大的代码。 5. **编译时算术和逻辑...

    BOOST程序库完全开发指南(PDF高清版)

    1. **模板元编程**:BOOST库中的Boost.MPL(Meta-Programming Library)提供了一种在编译时进行计算的方法,这对于创建高度定制化和高效的代码非常有用。 2. **智能指针**:如Boost.PtrContainer和Boost.SmartPtr,...

    the_boost_c _metaprogramming.

    标签中的“boost”,“c++_meta”和“programming”揭示了文档的焦点是关于Boost库、C++中的元编程技术以及通用编程的实践。 从提供的内容片段中,我们可以看到,文档提到了Boost C++元编程库的作者Aleksey ...

Global site tag (gtag.js) - Google Analytics