输入迭代器可以重复读取,而输出迭代器只能写入一次?

时间:2019-01-31 19:04:51

标签: c++ c++11 iterator input-iterator

我正在阅读Bjarne Stroustrup撰写的 C ++编程语言第4版。在迭代器一章(第31.1.2章)中,它表示:

  

输入迭代器:我们可以使用++进行迭代,并使用*读取每个元素(反复)。

     

输出迭代器:我们可以使用++进行迭代,并使用*编写元素仅一次

我对输入迭代器是否只能读取一次或重复读取进行了很多搜索,例如: http://www.cplusplus.com/reference/iterator/InputIterator/ https://www.geeksforgeeks.org/input-iterators-in-cpp/

多数建议输入迭代器只能读取一次。但是为什么作者反复对输入迭代器说呢?它是否正确?如果是这样,为什么输入迭代器可以被重复读取而输出迭代器只能被写入一次。我一直以为输入和输出迭代器是完全相反的。

谢谢大家!

3 个答案:

答案 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 迭代器,对通过同一迭代器进行的多个分配的限制就会消失。