We began this chapter looking at algorithms such as std::find that march through a range reading its elements in order without modification. You might be surprised to learn that the inverse operation also makes sense: there is a family of standard algorithms that march through a range modifying each element without reading it!
std::fill(a,b,v) does what its name implies: fill each element of the given range [a,b) with a copy of the provided value v.
std::iota(a,b,v) is slightly more interesting: it fills the elements of the given range with copies of ++v. That is, std::iota(a,b,42) will set a[0] equal to 42, a[1] equal to 43, a[2] equal to 44, and so on all the way up to b. This algorithm's funny name comes from the APL programming language, where a function named ι (that's the Greek letter iota) performed this operation. Another funny thing about this algorithm is that, for whatever reason, its definition is found in the standard <numeric> header instead of in <algorithm>. It's just an oddball that way.
std::generate(a,b,g) is even more interesting: it fills the elements of the given range with the successive results of g(), whatever it is:
template<class FwdIt, class T> void fill(FwdIt first, FwdIt last, T value) { while (first != last) { *first = value; ++first; } }
template<class FwdIt, class T> void iota(FwdIt first, FwdIt last, T value) { while (first != last) { *first = value; ++value; ++first; } }
template<class FwdIt, class G> void generate(FwdIt first, FwdIt last, G generator) { while (first != last) { *first = generator(); ++first; } }
Here's an example of using each of these standard algorithms to fill a vector of strings with different contents. Test your understanding: do you understand why each call produces the output that it does? The example I picked for std::iota is particularly interesting (yet unlikely to be helpful in real-world code):