12

在示例代码中,我经常看到诸如*it++输出迭代器之类的代码。该表达式*it++复制it, 递增it,然后返回最终取消引用的副本。据我了解,制作输出迭代器的副本会使源无效。但是it在创建副本之后执行的增量是非法的,对吗?我对输出迭代器的理解有缺陷吗?

4

5 回答 5

16

该标准要求*r++ = t输出迭代器(24.1.2)工作。如果它不起作用,则它不是标准定义的输出迭代器。

由迭代器实现来确保此类语句在后台正常工作。

您不应该保留输出迭代器的多个副本的原因是它具有单遍语义。迭代器只能在每个值处取消引用一次(即,它必须在每次取消引用操作之间递增)。一旦迭代器被取消引用,它的副本就不能被取消引用。

这就是为什么*r++ = t有效。复制原始迭代器,取消引用原始迭代器并增加副本。原始迭代器将永远不会再次使用,并且副本不再引用相同的值。

于 2010-10-22T23:06:23.320 回答
7

表达式*it++不(必须)复制它,不增加它,等等。这个表达式只是为了方便才有效,因为它遵循通常的语义只做operator=实际工作。例如,在 g++ 中 , 和 的实现中ostream_iterator只做一operator*件事:(换句话说,什么都不做!)。例如,我们可以这样写:operator++operator++(int)return *this

it = 1;
it = 2;
*it = 3;
++it = 4;

代替:*it++ = 1; *it++ = 2; *it++ = 3; *it++ = 4;

于 2010-10-23T12:52:17.293 回答
1

输出迭代器只是不像普通迭代器那样工作,并且它们的接口被指定,以便它们可以在类似指针的表达式(*it++ = x)中使用并获得有用的结果。

通常,operator*(),operator++()operator++(int)所有返回*this作为参考和输出迭代器具有operator=执行预期输出操作的魔力。因为您无法从输出迭代器中读取,所以operator*()不能像其他迭代器那样工作的事实并不重要。

于 2010-10-22T23:04:42.563 回答
1

查看您的评论,似乎大部分混淆都来自 SGI 文档,我想说这在这一点上有点误导。

复制输出迭代器不会使复制的迭代器无效。真正的限制非常简单:您应该只取消引用输出迭代器的给定值一次。但是,一次拥有两个副本是可以的,只要您在它们具有相同值时只取消引用其中一次。在像这样的情况下,您要取消引用一个,然后丢弃它的值,并增加另一个但仅在增量发生后才取消引用它,这一切都很好。

于 2010-10-22T23:37:25.907 回答
-4

迭代器不只是一个指针吗?递增,然后取消引用它只是移动到下一个元素。

于 2010-10-22T22:56:01.257 回答