作者 | David Abrahams, Jeremy Siek, Thomas Witt |
---|---|
联系方式 | dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com |
组织 | Boost Consulting, Indiana University Open Systems Lab, Zephyr Associates, Inc. |
版权 | Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003. |
摘要 | Boost Iterator 库包含两个部分。第一部分是 概念 系统,它扩展了 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_facade和iterator_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(或Reference模板参数,如果显式指定)是真引用类型,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. |