The default istreambuf_iterator
is basically an end-of-file iterator, i.e. another iterator will only be compared with it when it reaches the end of the file.
Therefore, the code:
std::vector<char> v( (std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>() );
... reads char
from in
until the first iterator is incremented to equal the second iterator, which will happen when (and only when) the first iterator reaches the end of the file (stringstream, in this case). In short, it copies the entire contents of a file to a vector.
The printed part of "hello world" is a bit simpler: ostream has an operator<<
overload for char *
, which assumes that char *
points to a C-style string, so it should print the entire line that pointed to. Since they did push_back
to add the string '\0'
to the string, this makes it a string of type C.
The second part demonstrates that although you have two iterators in a stream, you still only have one stream and one read position in that stream. At the same time, each iterator contains a copy of the last element that it reads from the stream.
Therefore, at any time, when you increase either an iterator (or any iterator in one thread), it increases the current reading position. So, you start with i1
and i2
, indicating the beginning of the stream. Then you increase i1
. This increases the reading position and reads b
in i1
, so when you look for i1
, this is what you get. When you increment i2
, it moves the read position again and reads c
in i2
, so dereferencing i2
will give c
.
In short, using two (or more) iterators does not change the nature of the stream - every time you increment any iterator in the same stream that reads the next element from this stream - and the "next element" is always determined by the stream itself, based on its one read position.