| 作者 | David Abrahams, Jeremy Siek, Thomas Witt |
|---|---|
| 联系方式 | dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com |
| 组织 | Boost Consulting, 印第安纳大学 Open Systems Lab, Zephyr Associates, Inc. |
| 版权 | 版权所有 David Abrahams, Jeremy Siek, Thomas Witt 2003。 |
| 摘要 | Boost Iterator 库包含两部分。第一部分是一套扩展了 C++ 标准迭代器需求的概念 (concepts)。第二部分是一个构建基于这些扩展概念的迭代器的组件框架,并包含若干实用的迭代器适配器。扩展的迭代器概念经过精心设计,使得旧式迭代器可以适配新概念,新式迭代器也可以与旧式算法兼容,尽管如果算法想要充分利用新式迭代器的能力,可能需要进行更新。该库的几个组件已被纳入 C++ 标准技术报告。Boost Iterator 库的组件取代了旧有的 Boost Iterator Adaptor 库。 |
|---|
C++98 中定义的迭代器类别极其受限,因为它们将两个正交的概念捆绑在一起:遍历和元素访问。例如,由于随机访问迭代器在解引用时必须返回一个引用(而不是代理),因此无法用 C++98 的类别捕获vector<bool>::iterator的功能。这就是臭名昭著的“vector<bool>不是容器,且其迭代器不是随机访问迭代器”的争论,Herb Sutter 为此向标准委员会写了两篇论文(n1185 和 n1211),以及一篇 Guru of the Week 文章。然而,新式迭代器不仅仅是为了修补vector<bool>:现有的许多迭代器已经在使用中,但无法用现有的概念充分表达。有关新迭代器概念的详细信息,请参阅我们的
新式迭代器标准提案 (PDF)
编写符合标准的迭代器很棘手,但这种需求经常出现。为了简化新迭代器的实现,Boost.Iterator 库提供了iterator_facade类模板,它实现了许多有用的默认设置和编译时检查,旨在帮助迭代器作者确保其迭代器是正确的。
通常还需要定义一个类似于底层迭代器或类迭代器类型的新迭代器,但要修改底层类型行为的某些方面。为此,该库提供了iterator_adaptor类模板,它是专门为最大限度地利用底层类型行为而设计的。
这两个类的文档可以在以下网页中找到
两者iterator_facadeanditerator_adaptor以及下文提到的许多专用适配器已被提议标准化,并被纳入第一个 C++ 技术报告;详情请参阅我们的
迭代器 Facade 和 Adaptor 标准提案 (PDF)
以了解更多细节。
迭代器库提供了一套基于 Boost 迭代器 facade 和 adaptor 的、符合标准的实用迭代器模板。
如果您一直使用旧的 Boost Iterator Adaptor 库来实现迭代器,您可能编写过一个策略类来捕获迭代器的核心操作。在新的库设计中,您将把这些核心操作移动到迭代器类本身中。如果您曾编写过一系列迭代器,您可能编写了一个类型生成器来构建所需的iterator_adaptor特化版本;在新的库设计中,您不需要类型生成器(尽管可以保留它以兼容旧代码),因为通过使用“奇异递归模板模式”(CRTP) [Cop95],您现在可以自己定义迭代器类,并通过继承iterator_facade或iterator_adaptor来获取功能。结果是,您还可以更精细地控制迭代器的工作方式:您可以添加额外的构造函数,甚至覆盖库提供的迭代器功能。
如果您在寻找旧的projection_iterator组件,它的功能已经合并到了transform_iterator中:只要函数对象的result_type(或参考模板参数,如果显式指定的话)是一个真正的引用类型,transform_iterator的行为就会像以前的projection_iterator一样。
2000 年,Dave Abrahams 正在为指针容器编写一个迭代器,它在解引用时会访问所指向的元素。作为一个库编写者,他自然决定将这个想法推广,于是 Boost Iterator Adaptor 库诞生了。Dave 受到了 Andrei Alexandrescu 一些著作的启发,选择了基于策略的设计(尽管他可能没有很好地领会 Andrei 的想法——所有迭代器的正交属性只用了一个策略类)。Jeremy Siek 很快意识到他也需要这个库,于是他们合作编写了一个“Boost 化”版本,经过审查并被纳入库中。他们写了一篇论文并对代码进行了几次重要的修订。
最终,旧库的几个缺陷使重写的需求变得明显。Dave 和 Jeremy 在 2002 年圣克鲁兹 C++ 委员会会议上开始着手工作,并很快生成了一个可用的原型。在 Mat Marcus 的敦促下,他们决定使用 GenVoca/CRTP 模式方法,并将策略移入迭代器类本身。Thomas Witt 表达了兴趣并成为该项目中严格编译时检查的倡导者,加入了 SFINAE 技术的使用,以消除重载集中错误的转换构造函数和运算符。他还认识到需要一个单独的iterator_facade,并将其从iterator_adaptor中剥离出来。最终,在对原型进行近乎彻底的重写后,他们拿出了您今天看到的这个库。
| [Cop95] | [Coplien, 1995] Coplien, J., Curiously Recurring Template Patterns, C++ Report, February 1995, pp. 24-27。 |