c++ - Is generate Guaranteed to be Executed Sequentially? -
i told here that:
the order of generate not guaranteed => depending on implementation
i have looked gcc's implementation of generate
:
(; __first != __last; ++__first) *__first = __gen();
and visual studio implements identically that. relief me using lambda in generate
reads , writes capture have undeterministic results:
int foo[] = {1, 0, 13}; vector<int> bar(3); generate(bar.begin(), bar.end(), [&]() { static auto = 0; static auto total = 0; total += foo[i]; return foo[i] / total; });
i expect bar
contain {1, 0, 0}
.
if allowed execute out of order cause divide 0 error.
so i'd sleep easier if question answered proof generate
required execute sequentially.
as note here, know experimental::parallel::generate
not sequential. i'm asking generate
.
i intrigued have done research.
at bottom of answer copy of relevant section standard of 2011.
you see template declaration of std::generate<>
iterator parameters must conform concept of forwarditerator
, outputiterator
respectively.
a forwarditerator does not support random access. can read or write sequentially. outputiterator
more restrictive - operator*
implicitly includes effect of operator++
. explicit feature of concept.
therefore, implication, implementation of function must access elements sequentially (and therefore generate values sequentially) since to not break contract implicit in interface.
therefore standard does (implicitly , quietly) guarantee std::generate
initialise elements sequentially. impossible write well-formed implementation of std::generate
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: first algorithm invokes function object gen , assigns return value of gen through iterators in range [first,last). second algorithm invokes function object gen , assigns return value of gen through iterators in range [first,first + n) if n positive, otherwise nothing.
2 requires: gen takes no arguments, size shall convertible integral type (4.7, 12.3).
3 returns: generate_n returns first + n non-negative values of n , first negative values.
4 complexity: last - first, n, or 0 invocations of gen , assignments, respectively.
Comments
Post a Comment