递增可变输入迭代器是否会使旧迭代器值失效

Does incrementing a mutable input iterator invalidate old iterator values?

本文关键字:迭代器 失效 是否 输入      更新时间:2023-10-16

进一步满足输出迭代器要求的迭代器称为可变迭代器。不可变迭代器称为常量迭代器。[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声称它需要一个代理对象?(链接是代码;向下滚动以阅读struct writable_postfix_increment_proxypostfix_increment_result的评论)。也就是说,如果可以返回旧迭代器值的(可取消引用)副本,为什么需要将此副本包装在代理中?

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

在以下情况下,aX 类型的b两个可取消引用迭代器提供多通道保证

a == b意味着++a == ++b
X 是指针类型,或者表达式 (void)++X(a), *a 等效于表达式 *a

[ 注意:a == b 意味着++a == ++b的要求(对于输入和输出迭代器来说并非如此)以及通过可变迭代器(适用于输出迭代器)消除对赋值数量的限制允许使用带有前向迭代器的多通道单向算法。 —尾注 ]

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

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

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

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