在示例代码中,我经常看到*it++
等代码用于输出迭代器。表达式*it++
复制it
,递增it
,然后返回最终解除引用的副本。据我了解,制作输出迭代器的副本会使源无效。但是,创建副本后执行的it
增量是非法的,对吧?我对输出迭代器的理解有缺陷吗?
答案 0 :(得分:14)
该标准要求*r++ = t
适用于输出迭代器(24.1.2)。如果它不起作用,它不是标准定义的输出迭代器。
由迭代器实现来确保这些语句在引擎盖下正常工作。
您不应该保留输出迭代器的多个副本的原因是它具有单遍语义。迭代器只能在每个值处解除引用一次(即它必须在每个解除引用操作之间递增)。一旦解除引用迭代器,它的副本就不能。
这就是*r++ = t
有效的原因。副本由原始迭代器构成,原始迭代器被解除引用并且副本递增。永远不会再使用原始迭代器,并且副本不再引用相同的值。
答案 1 :(得分:6)
表达式*it++
不(必须)复制它,不递增它等等。
此表达式仅为方便起见,因为它遵循通常的语义。只有operator=
才能完成实际工作。例如,在ostream_iterator
的g ++实现中,operator*
,operator++
和operator++(int)
仅执行一个事物:return *this
(在其他情况下)没有!)。我们可以写一下例如:
it = 1;
it = 2;
*it = 3;
++it = 4;
而不是:*it++ = 1; *it++ = 2; *it++ = 3; *it++ = 4;
答案 2 :(得分:1)
输出迭代器只是不像普通迭代器一样工作,并且它们的接口被指定,以便它们可以在类似指针的表达式(*it++ = x
)中使用,并带来有用的结果。
通常,operator*()
,operator++()
和operator++(int)
都返回*this
作为引用,输出迭代器有一个魔术operator=
,它执行预期的输出操作。因为你无法从输出迭代器中读取,operator*()
等不能像其他迭代器那样工作的事实并不重要。
答案 3 :(得分:1)
看看你的评论,似乎大多数混淆都来自SGI文档,我认为这在这一点上有点误导。
复制输出迭代器不使复制的迭代器无效。真正的限制很简单:你应该只取消引用一次输出迭代器的给定值。但是,一次拥有两个副本就没问题,只要你只有一个副本,它们具有相同的值。在那种情况下你要解除引用它,然后丢弃它的值,然后递增另一个但只是在增量发生后才解除引用它,这一切都很好。
答案 4 :(得分:-4)
迭代器不是指针吗?递增,然后取消引用它只会转移到下一个元素。