I was intrigued by this so have done some research.
At the bottom of this answer is a copy of the relevant section from the standard as of 2011.
You will see from the template declaration of std::generate<>
that the iterator parameters must conform to the concept of a ForwardIterator
and OutputIterator
respectively.
A ForwardIterator does not support random access. it can only read or write sequentially. An OutputIterator
is even more restrictive - its operator*
implicitly includes the effect of an operator++
. This is an explicit feature of the concept.
Therefore, by implication, the implementation of this function must access elements sequentially (and therefore generate values sequentially) since to not do so would break the contract implicit in the interface.
Therefore the standard does (implicitly and quietly) guarantee that std::generate
initialise its elements sequentially. It would be impossible to write a well-formed implementation of std::generate
that did not.
QED
25.3.7 Generate [alg.generate]
template<class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last,
Generator gen);
template<class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen);
1 Effects: The first algorithm invokes the function object gen and
assigns the return value of gen through all the iterators in the range
[first,last). The second algorithm invokes the function object gen and
assigns the return value of gen through all the iterators in the range
[first,first + n) if n is positive, otherwise it does nothing.
2
Requires: gen takes no arguments, Size shall be convertible to an
integral type (4.7, 12.3).
3 Returns: generate_n returns first + n for
non-negative values of n and first for negative values.
4 Complexity:
Exactly last - first, n, or 0 invocations of gen and assignments,
respectively.