为什么 InputIterators 只有一次传递?

Why are InputIterators one pass only?

提问人:Luchian Grigore 提问时间:4/10/2013 更新时间:4/10/2013 访问量:726

问:

24.2.3 输入迭代器 [input.iterators]

3) [...]输入迭代器上的算法不应尝试传递 通过同一个迭代器两次。它们应该是单通道算法。[...]

这个 IMO 限制了一些相当直接的优化(例如通过容器一次以查看它有多少元素)——唉,动机超出了问题的范围。

为什么有这个要求?

C++ 迭代器 语言设计

评论

1赞 PlasmaHH 4/10/2013
such as passing through the container once to see how many elements it has这就是为什么对于这样的算法,需要像正向甚至双向迭代器这样的东西。
0赞 Joseph Mansfield 4/10/2013
值得一提的是,Boost.Iterator 中的等效概念实际上称为单通道迭代器。

答:

4赞 Jon 4/10/2013 #1

所选的名称已经给出了原因的提示:将迭代器视为遍历输入流(如键盘输入或网络)。没有办法对一个流进行两次迭代,因此存在限制。

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

相关问题:输入迭代器和只读正向迭代器有什么区别?

评论

0赞 Joseph Mansfield 4/10/2013
如!std::istream_iterator
10赞 R. Martinho Fernandes 4/10/2013 #2

输入迭代器用于遍历没有实质性实现的范围(因为它们的元素实际上并不存在于内存中的某个地方),例如来自网络流的字节,或来自 /dev/random 的随机数序列。考虑最后一个示例:一旦使用第一个随机数,就无法再次检索它。

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

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

如果算法可以在一次传递中编写,则没有理由禁止将其与输入迭代器一起使用。但是,没有什么可以禁止这样的算法使用优化版本,该版本在给定正向或更好的迭代器时执行多次传递。


† 例如,所有偶数的范围不需要将容器中的所有数字具体化,但可以很容易地从给定的迭代器重新开始,因为重新计算数字是可能的,而且成本低廉。