2

I'm reading C++ Standard (Section Input Iterator) and I'm having hard time to visualize the text in bold:

Note: For input iterators, a == b does not imply ++a == ++b. (Equality does not guarantee the substitution property or referential transparency.) Algorithms on input iterators should never attempt to pass through the same iterator twice. They should be single pass algorithms.

I understand that input iterators are single pass, but I can't seem to visualize it in a C++ code. Can someone please show me in example on how to make iterator to become a single pass?

Orion
  • 544
  • 5
  • 15
  • What do you mean by "how to make iterator to become a single pass"? Why are they single pass? Or how to work with such iterators? – Revolver_Ocelot Feb 06 '16 at 22:27
  • I'm not sure what you are asking. Iterators are what they are; they don't "become" anything . Are you asking for an example of an iterator that is not multipass? If so, consider one that reads from `stdin` – M.M Feb 06 '16 at 23:54
  • @Revolver_Ocelot Sorry for not being clear, I want to create input iterator from scratch (not using STL or boost) for learning. I just don't know how make my input iterator class to become single pass (force single pass)? In my understanding it is a job of the underlying container or stream (`stdin`) to make the iterator as input or forward iterator, am I right? – Orion Feb 07 '16 at 20:31
  • You don't force an iterator to be single-pass, it is usually a side effect, e.g. from reading input once and discarding previous values. – Ulrich Eckhardt Feb 07 '16 at 21:05
  • @ManiH. Input iterators do not force single pass. THey just do not work as expected if you will try to make a second pass: stream iterators will just read next entry from a stream instead of returning earlier value, move iterators might invoke undefined behavior on second pass, etc. – Revolver_Ocelot Feb 07 '16 at 21:06
  • @Revolver_Ocelot Containers have a pointer to head/root which begin() in container creates object of input_iterator by passing head/root pointer to the input_iterator. In order my input_iterator to work the way you explained, my constructor in input_iterator must get that pointer (root/head pointer) by reference, is that correct? This way ++ operator in my iterator moves the actual head/root pointer instead of the copy one. – Orion Feb 13 '16 at 19:28
  • @ManiH. most actual containers usually support at least forward iterators. If you copy forward iterator and advance copy original one will be still dereferencable and point to same element. – Revolver_Ocelot Feb 13 '16 at 20:09

1 Answers1

2

Suppose you want to read integers from the standard input. One way to do so would be using

#include <iterator>
#include <iostream>
#include <vector>

using namespace std;

const vector<int> v{istream_iterator<int>{cin}, istream_iterator<int>{}};

This will read integers into v (see istream_iterator).

In this case, it makes a lot of sense that the iterators will be single pass, since the range is something that is just created on the fly, as the user types in things, and each element is consumed and disappeared. You can't reiterate this range.


Other than that, not so sure what you mean by

how to make iterator to become a single pass?

  • If you mean "how to signify that an iterator class you're writing has this restriction?", then set its iterator_category to input_iterator_tag

    struct my_iterator
    {
        using iterator_category = input_iterator_tag;
    };
    
  • If you want to query (at compile time) whether an iterator class has this restriction, use iterator_traits.

Orion
  • 544
  • 5
  • 15
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
  • Forward iterators are multipass, did you meant `input_iterator_tag` ? – M.M Feb 06 '16 at 23:52
  • @M.M One of the numerous times I need to thank you for a useful comment. Many thanks! – Ami Tavory Feb 07 '16 at 00:03
  • @AmiTavory Sorry for not being clear, I want to create input iterator from scratch (not using STL or boost) for learning. I just don't know how make my input iterator class to become single pass (force single pass)? In my understanding it is a job of the underlying container or stream (`stdin`) to make the iterator as input or forward iterator, am I right? – Orion Feb 07 '16 at 20:31
  • @ManiH. Not quite - it is the job of the iterator to notify others what are its capabilities. I suggest you read [this tutorial](http://web.stanford.edu/class/cs107l/handouts/04-Custom-Iterators.pdf), which I think is quite good. – Ami Tavory Feb 07 '16 at 20:56