Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do std::generate() and std::generate_n() require different iterators?

I was looking at generate() and generate_n() in cppreference and am trying to understand why does generate() require ForwardIterator, whereas generate_n() requires OutputIterator for the range? (I checked the latest working draft of the Standard, and it's the same requirement.)

Because, at least their possible implementations seem to require identical iterator concepts and OutputIterator seems to be enough:

generate():

template<class ForwardIt, class Generator> void generate(ForwardIt first, ForwardIt last, Generator g) {     while (first != last) {         *first++ = g();     } } 

generate_n():

template<class OutputIt, class Size, class Generator> OutputIt generate_n(OutputIt first, Size count, Generator g) {     for (Size i = 0; i < count; i++) {         *first++ = g();     }     return first; } 

Same story with std::fill() and std::fill_n().

like image 992
Sofya Torosyan Avatar asked Jul 22 '17 11:07

Sofya Torosyan


1 Answers

at least their possible implementations seem to require identical iterator concept and OutputIterator seems to be enough

OutputIterator doesn't support equality / inequality comparison (including operator!= used in the possible implementation of generate() you showed) and multipass guarantee, while ForwardIterator does. That means OutputIterator can't be used for representing a range via two iterators (e.g. [first, last)) which is required by generate()'s interface.

Equality and inequality may not be defined for output iterators. Even if an operator== is defined, x == y need not imply ++x == ++y.

like image 144
songyuanyao Avatar answered Sep 21 '22 11:09

songyuanyao