I'm having a hard time seeing the practical difference between std::fill_n
and std::ranges::fill_n
.
There are a few main differences that apply to all the std
vs std::ranges
algorithms:
The ones in std::ranges
are constrained with concepts, so are much stricter in what they accept. It is common when migrating code using custom iterators that the iterator isn't quite an input_iterator
(usually because of missing something like difference_type
) so will need to be updated. The ones in std::ranges
also are based on the C++20 iterator concepts, not the C++98 ones - so there are slight differences there too (most notably that you are allowed to have a forward or better iterator that gives you prvalues).
The ones in std::ranges
are function objects, not function templates. Technically they're "niebloids", but the only way to implement them to get the required standard behavior is as a function object, and it is likely the case that they will soon be specified as such.
Many of the algorithms have additional differences - most notably accepting a range rather than a pair of iterators. Many also have projection arguments in addition to the callables. Many also have a different return type from their std::
counterpart.
But fill_n
specifically doesn't have those extra overloads or arguments or have a distinct return type - std::ranges::fill_n
is the same as std::fill_n
except for the differences I laid out earlier. You can think of std::ranges::fill_n
existing primarily so that every std::meow
has a std::ranges::meow
counterpart, so that you can wholesale switch to std::ranges
without having to think about it.