Home > front end >  Do you have to increment ostream_iterator when writing?
Do you have to increment ostream_iterator when writing?

Time:12-22

In many examples of ostream_iterator I notice that an increment operation is used between writes:

e.g.

#include <iostream>
#include <iterator>

using namespace std;

int main() {
  ostream_iterator<char> itr{ cout };
  *itr = 'H';
    itr; // commenting out this line appears to yield the same output
  *itr = 'i';
}

On the cpp reference increment (operator ) is listed as a no-op. Is there a reason to include it despite being a no-op? Is it a "best-practice" to include?

CodePudding user response:

Why does ostream_iterator exist at all, when you can print directly to cout?

Answer: to be used with functions that expect an iterator.

There is a bunch of requirements that a type has to satisfy to be "an iterator" (and that those functions expect), and overloading and * in a certain way is one of them.

Both * and do nothing for an ostream iterator. If you're asking if you should call them or not, you don't need ostream_iterator in the first place.

CodePudding user response:

Consider a possible implementation of std::copy:

template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last, 
              OutputIt d_first)
{
    for (; first != last; (void)  first, (void)  d_first) {
        *d_first = *first;
    }
    return d_first;
}

This code works with all output iterators. It also works with std::ostream_iterator. d_first is a noop in this case, but it still it has to be valid code, because for other output iterators it is needed.

Actually the major reason for std::ostream_iterator to exists is to be used with such generic algorithms, otherwise you could just write to the stream directly. Its a nice example of iterators being the glue between algorithms and container or more generally the data. Algorithms can be generic and need not care where the data is actually coming from or going to, because the iterator implements the special case.

Also from cppreference on std::ostream_iterator::operator :

Does nothing. These operator overloads are provided to satisfy the requirements of LegacyOutputIterator. They make it possible for the expressions *iter =value and * iter=value to be used to output (insert) a value into the underlying stream.

For your actual question:

Is there a reason to include it despite being a no-op? Is it a "best-practice" to include?

No. There is no point in incrementing the iterator when you know its a std::ostream_iterator. The only reason it can be incremented (which is a noop) is for generic code.

  •  Tags:  
  • c
  • Related