在示例代码中,我经常看到诸如*it++
输出迭代器之类的代码。该表达式*it++
复制it
, 递增it
,然后返回最终取消引用的副本。据我了解,制作输出迭代器的副本会使源无效。但是it
在创建副本之后执行的增量是非法的,对吗?我对输出迭代器的理解有缺陷吗?
5 回答
该标准要求*r++ = t
输出迭代器(24.1.2)工作。如果它不起作用,则它不是标准定义的输出迭代器。
由迭代器实现来确保此类语句在后台正常工作。
您不应该保留输出迭代器的多个副本的原因是它具有单遍语义。迭代器只能在每个值处取消引用一次(即,它必须在每次取消引用操作之间递增)。一旦迭代器被取消引用,它的副本就不能被取消引用。
这就是为什么*r++ = t
有效。复制原始迭代器,取消引用原始迭代器并增加副本。原始迭代器将永远不会再次使用,并且副本不再引用相同的值。
表达式*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;
输出迭代器只是不像普通迭代器那样工作,并且它们的接口被指定,以便它们可以在类似指针的表达式(*it++ = x
)中使用并获得有用的结果。
通常,operator*()
,operator++()
和operator++(int)
所有返回*this
作为参考和输出迭代器具有operator=
执行预期输出操作的魔力。因为您无法从输出迭代器中读取,所以operator*()
不能像其他迭代器那样工作的事实并不重要。
查看您的评论,似乎大部分混淆都来自 SGI 文档,我想说这在这一点上有点误导。
复制输出迭代器不会使复制的迭代器无效。真正的限制非常简单:您应该只取消引用输出迭代器的给定值一次。但是,一次拥有两个副本是可以的,只要您在它们具有相同值时只取消引用其中一次。在像这样的情况下,您要取消引用一个,然后丢弃它的值,并增加另一个但仅在增量发生后才取消引用它,这一切都很好。
迭代器不只是一个指针吗?递增,然后取消引用它只是移动到下一个元素。