| 作者 | 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 库包含两部分。第一部分是概念(concept)系统,它扩展了 C++ 标准的迭代器需求。第二部分是构建迭代器的组件框架,基于这些扩展的概念,并包含几个有用的迭代器适配器。扩展的迭代器概念经过精心设计,以便旧式迭代器可以融入新概念,并且新式迭代器可以与旧式算法兼容,尽管算法可能需要更新才能充分利用新式迭代器的功能。该库的几个组件已被接受为 C++ 标准技术报告的一部分。Boost Iterator 库的组件取代了旧的 Boost Iterator Adaptor 库。 |
|---|
C++98 中定义的迭代器类别极其受限,因为它们将两个正交的概念:遍历和元素访问绑在了一起。例如,由于随机访问迭代器需要返回一个引用(而不是代理)才能解引用,因此不可能捕获vector<bool>::iterator使用 C++98 类别的能力。这就是臭名昭著的“vector<bool>不是容器,并且其迭代器不是随机访问迭代器”的困境,Herb Sutter 就此为标准委员会撰写了两篇论文(n1185 和 n1211),以及一篇 Guru of the Week。新式迭代器远不止是修补vector<bool>那么简单:还有许多其他已在使用的迭代器,它们无法被现有概念充分表示。有关新迭代器概念的详细信息,请参阅我们的
新式迭代器概念标准提案(PDF)
编写符合标准的迭代器非常棘手,但需求却经常出现。为了简化新迭代器的实现,Boost.Iterator 库提供了iterator_facade类模板,它实现了许多有用的默认设置和编译时检查,旨在帮助迭代器作者确保其迭代器的正确性。
通常还需要定义一个新的迭代器,它与某个底层迭代器或类似迭代器的类型相似,但会修改底层类型行为的某些方面。为此,该库提供了iterator_adaptor类模板,它专门设计用于充分利用底层类型的尽可能多的行为。
关于这两个类的文档可以在以下网页找到:
两者iterator_facadeanditerator_adaptor以及下文提到的许多 专用适配器 已被提议标准化,并被纳入了第一个 C++ 技术报告;请参阅我们的
迭代器外观和适配器标准提案(PDF)
了解更多详情。
迭代器库提供了基于 Boost 迭代器外观和适配器 的一组有用的标准兼容迭代器模板。
如果您之前使用旧的 Boost Iterator Adaptor 库来实现迭代器,您可能编写了一个策略类,它捕获了您的迭代器的核心操作。在新库设计中,您将把相同的核心操作移入迭代器类本身的主体中。如果您正在编写一系列迭代器,您可能编写了一个 类型生成器 来构建您需要的iterator_adaptor特化;在新库设计中,您不需要类型生成器(尽管为了与旧代码兼容,您可能仍想保留它),因为由于使用了“自递归模板模式”(Curiously Recurring Template Pattern, 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。 |