我正在阅读Bjarne Stroustrup撰写的 C ++编程语言第4版。在迭代器一章(第31.1.2章)中,它表示:
输入迭代器:我们可以使用++进行迭代,并使用*读取每个元素(反复)。
输出迭代器:我们可以使用++进行迭代,并使用*编写元素仅一次。
我对输入迭代器是否只能读取一次或重复读取进行了很多搜索,例如: http://www.cplusplus.com/reference/iterator/InputIterator/ https://www.geeksforgeeks.org/input-iterators-in-cpp/
多数建议输入迭代器只能读取一次。但是为什么作者反复对输入迭代器说呢?它是否正确?如果是这样,为什么输入迭代器可以被重复读取而输出迭代器只能被写入一次。我一直以为输入和输出迭代器是完全相反的。
谢谢大家!
答案 0 :(得分:2)
这本书是正确的;而矛盾的来源则不是。似乎没有规则允许通过输入迭代器间接读取一个对象不止一次。
其他来源可能会由于另一个类似的限制而感到困惑,那就是一旦输入迭代器增加,先前迭代器的所有副本都会失效,因此可能不再被间接使用。此限制由输出迭代器共享。例如:
value = *inputIt;
value = *inputIt; // OK
copyIt = inputIt;
++inputIt;
value = *copyIt; // Not OK
这本书是正确的,因为输出迭代器确实具有局限性:
*outputIt = value;
++outputIt;
*outputIt = value; // OK
*outputIt = value; // Not OK
我一直以为输入和输出迭代器是完全相反的。
许多输出迭代器也都是输入迭代器,因此“对立”并不是非常准确的描述。它们是部分重叠的需求。迭代器可以同时满足两组要求。
如果我们有* outputIt = 1;然后* outputIt = 2;难道我们不只是两次分配相同的* outputit吗?
是;不需要输出迭代器支持。
例如考虑一个输出迭代器,该迭代器通过Internet发送数据包。您已经编写了一个数据包,该数据包已发送到互联网并被其他计算机接收。您无法及时返回并确定发送的数据包有所不同。您必须移至下一个数据包并发送。
答案 1 :(得分:2)
Bjarne的报价正确。如果您有输入迭代器,则可以根据需要执行*iterator
次。如果您有输出迭代器,则只能执行一次*iterator
。
尽管它们的共同点是只能在单遍算法中使用。一旦增加了输入迭代器或输出迭代器,则不再需要将迭代器移至先前位置即可
这意味着
while (iterator != end)
{
if (*iterator == some_value)
something = *iterator;
++iterator;
}
iterator
必须是输入迭代器,因为我们在每次迭代中都将其取消引用两次。另一方面
while (iterator != end)
{
something = *iterator;
++iterator;
}
可同时用于输入和输出迭代器,因为我们仅执行一次取消引用。
答案 2 :(得分:1)
您可以根据需要多次遍历输入迭代器。这是因为“ (void)*a, *a
等于*a
”的要求[input.iterators],请参见表。
您只能通过输出迭代器编写一次。对于*r = o
,“此操作后r
不需要取消引用”。 [output.iterators],请参见表。递增r
后,您将拥有一个新的迭代器,并且可以再次通过它进行分配。
一旦将两者组合成 forward 迭代器,对通过同一迭代器进行的多个分配的限制就会消失。