Search code examples
c++c++11iteratorinput-iterator

Input iterator can be read repeatedly while Output Iterator can only be written once?


I was reading The C++ Programming Language 4th edition by Bjarne Stroustrup. In the iterator chapter (Chapter 31.1.2), it says:

Input iterator: We can iterate forward using ++ and read each element (repeatedly) using *.

Output iterator: We can iterate forward using ++ and write an element once only using *.

I have done many searches on whether input iterator can be read only once or repeatedly, for example: http://www.cplusplus.com/reference/iterator/InputIterator/ https://www.geeksforgeeks.org/input-iterators-in-cpp/

and most suggests that input iterator can be read once only. But why the author says repeatedly for the input iterator? Is this correct? And if so, why input iterator can be read repeatedly but output iterator can only be written once. I always thought input and output iterator are completely opposite of each other.

Thanks everyone!


Solution

  • The book is correct; and the contradicting sources are not. There appears to be no rule that disallows reading an object more than once by indirecting through an input iterator.

    The other sources may be confused by another similar limitation which is that once input iterator has been incremented, all copies of the previous iterator are invalidated, and thus may not be indirected anymore. This limitation is shared by output iterators. By example:

    value = *inputIt;
    value = *inputIt; // OK
    copyIt = inputIt;
    ++inputIt;
    value = *copyIt;  // Not OK
    

    The book is also correct that output iterator does have the limitation:

     *outputIt = value;
      ++outputIt;
     *outputIt = value; // OK
     *outputIt = value; // Not OK
    

    I always thought input and output iterator are completely opposite of each other.

    Many output iterators are also input iterators, so "opposite" isn't exactly very descriptive. They are partially overlapping sets of requirements. An iterator can meet both sets of requirements.

    If we have *outputIt = 1; then *outputIt = 2; aren't we just assigning to the same *outputit twice?

    Yes; And that's something that output iterators are not required to support.

    Consider for example an output iterator that sends packets over the internet. You've written a packet, and it has been sent to the internet and received by some other machine. You can't travel back in time and decide that the packet that was sent is something different. You must move on to the next packet and send that instead.