9

进一步满足输出迭代器要求的迭代器称为可变迭代器。不可变迭代器被称为常量迭代器。[24.2.1:4]

这表明您可以有一个可变的输入迭代器,它同时满足输入和输出迭代器的要求。

在增加输入迭代器后,其旧值的副本不需要可取消引用 [24.2.3]。但是,标准对输出迭代器的规定并不相同。事实上,后缀增量的操作语义被给出为{ X tmp = r; ++r; return tmp; },这表明输出迭代器可能不会使旧迭代器值无效(副本)。

那么,增加一个可变输入迭代器可以使旧的迭代器副本失效吗?

如果是这样,您将如何支持类似X a(r++); *a = tX::reference p(*r++); p = t使用(例如)代理对象的代码?

如果不是,那么为什么boost::iterator声称它需要一个代理对象?(链接是代码;向下滚动以阅读关于structswritable_postfix_increment_proxy和的评论postfix_increment_result)。也就是说,如果您可以返回旧迭代器值的(可取消引用)副本,为什么需要将此副本包装在代理中?

4

2 回答 2

6

如果在下一节中找到解释,[24.2.5] 前向迭代器,其中说明了它们与输入和输出迭代器的区别:

两个可取消引用的迭代器ab类型在以下情况下X提供多遍保证

a == b暗示++a == ++b
X是指针类型或表达式(void)++X(a), *a等价于表达式*a

[注意:a == b隐含的要求++a == ++b(对于输入和输出迭代器不正确)以及通过可变迭代器(适用于输出迭代器)取消对赋值数量的限制允许使用多遍单具有前向迭代器的定向算法。——尾注]

不幸的是,必须将标准作为一个整体来阅读,并且解释并不总是您期望的那样。

于 2012-08-13T06:41:45.240 回答
4

输入和输出迭代器基本上被设计为允许单次遍历:描述每个元素只能访问一次的序列。

流就是一个很好的例子。如果您从标准输入或套接字读取,或写入文件,则只有流的当前位置。当您递增一个迭代器时,所有其他指向相同底层序列的迭代器都将失效。

前向迭代器允许多遍遍历,这是您需要的额外保证:它们确保您可以复制您的迭代器,增加原始迭代器,并且副本仍将指向旧位置,因此您可以从那里进行迭代。

于 2012-08-13T08:14:05.850 回答