为什么InputIterator只能通过一次

Why are InputIterators one pass only?

本文关键字:一次 InputIterator 为什么      更新时间:2023-10-16

来自

24.2.3输入迭代器[Input.iterators]

3( […]输入迭代器上的算法永远不应该尝试通过通过同一迭代器两次。它们应该是单程算法。[…]

这个IMO限制了一些相当直接的优化(比如遍历容器一次,看看它有多少元素(——唉,动机不在问题的范围内。

为什么要这样做?

输入迭代器用于对没有实质实现的范围进行迭代(id表示它们的元素实际上不存在于内存中的某个位置(,如网络流中的字节或/dev/random中的随机数序列。考虑最后一个例子:一旦消耗了第一个随机数,就没有办法再次检索它。

另一方面,前向迭代器提供对范围的访问,这些范围要么有实质性的实现(假设它们的所有元素实际上都存在于内存中的某个位置(,要么可以很容易地重新计算†。从本质上讲,容器通常提供前向迭代器:容器本身就是范围的具体化。

用输入迭代器定义的范围有时可以转换为用前向迭代器来定义的范围,只需将其具体化:只需使用单程将整个范围复制到一个容器中,然后在该容器上随意迭代。显然,这并非在所有情况下都是可取的,有时甚至不可能:有些范围,如/dev/random中的字节,是无限的,永远无法完全实现。

如果一个算法可以一次性编写,那么就没有理由禁止它与输入迭代器一起使用。然而,没有什么可以阻止这样的算法使用优化版本,该版本在给定正向或更好的迭代器时执行多次传递。


&匕首;例如,所有偶数的范围不需要在容器中实现所有数字,但可以很容易地从给定的迭代器重新开始,因为重新计算数字既可能又便宜。

选择的名称已经提示了原因:将迭代器视为在输入流上迭代,如键盘输入或网络流。无法对流进行两次迭代,因此存在限制。

在需要优化的情况下,我们不介意提高迭代器的要求,前向迭代器或更强大的迭代器是自然的选择。

相关问题:What';输入迭代器和只读前向迭代器之间的区别是什么?