进一步满足输出迭代器要求的迭代器称为可变迭代器。非可变迭代器称为常量迭代器。 [24.2.1:4]
这表明你可以有一个可变的输入迭代器,它满足输入和输出迭代器的要求。
在递增输入迭代器之后,其旧值的副本不需要是可解除引用的[24.2.3]。但是,标准对输出迭代器并没有相同的说法;事实上,后缀增量的操作语义为{ X tmp = r; ++r; return tmp; }
,表明输出迭代器可能不会使旧迭代器值(副本)无效。
那么,可以递增一个可变输入迭代器使旧迭代器副本无效吗?
如果是这样,您如何支持X a(r++); *a = t
或X::reference p(*r++); p = t
等代码与(例如)代理对象?
如果没有,那么为什么boost::iterator
声称它需要代理对象? (链接是代码;向下滚动以阅读struct
s writable_postfix_increment_proxy
和postfix_increment_result
上的评论。也就是说,如果您可以返回旧迭代器值的(可解除引用的)副本,为什么需要将此副本包装在代理中?
答案 0 :(得分:6)
如果在下一节[24.2.5]转发迭代器中找到解释,说明它们与输入和输出迭代器的区别:
如果出现以下情况,则
a
的两个可解除引用的迭代器b
和X
会提供多次通过保证:-
a == b
隐含++a == ++b
和
-X
是指针类型,或者表达式(void)++X(a), *a
等同于表达式*a
。[注意:
a == b
暗示++a == ++b
的要求(对于输入和输出迭代器不是这样)并且通过可变迭代器去除对赋值数量的限制(适用)输出迭代器)允许使用带前向迭代器的多通道单向算法。 - 后注]
不幸的是,标准必须作为一个整体阅读,并且解释并不总是您期望的。
答案 1 :(得分:4)
输入和输出迭代器基本上设计为允许单遍遍历:描述每个元素只能访问一次的序列。
Streams就是一个很好的例子。如果从stdin或套接字读取或写入文件,则只有流的当前位置。当您递增迭代器时,指向相同基础序列的所有其他迭代器都将失效。
前向迭代器允许多遍遍历,这是您需要的额外保证:它们确保您可以复制迭代器,增加原始值,并且副本仍然指向旧位置,因此您可以从那里迭代。