I don't really have any problems, I am just curious a little. I've been browsing SO and saw this
post. It is a pretty cool trick but does it offer any advantages over a plain old std::fill?
I've been playing around with it in the quick bench and it seems that it doesn't offer any advantages in terms of performance with both -Og and -O3 and obviously it doesn't help with readability. I just can't think of any reason to ever use it. I am a newbie in c++ and maybe I did something wrong so here is my code for fill version:
template<typename T, size_t N, typename... Ts>
auto make_fill_array(Ts&&... args) noexcept(std::is_nothrow_constructible<T>::value)
-> std::array<T, N> {
std::array<T, N> ret;
std::fill(ret.begin(), ret.end(), T{std::forward<Ts>(args)...});
return ret;
}
Also there is a template specialization for containers that are constructible with std::initializer_list but that's just some boilerplate.
Edit: I was asked about usage. I didn't really think this code through because it isn't part of my personal projects, it is just personal curiosity so my tests were simple stuff like this.
auto fillarray = make_fill_array<Point, 10>(1, 6);
or
auto fillarray2 = make_fill_array<std::vector<Point>, 5>(5, Point{1, 6});
This requires a lot more of T
than the pack-expansion solution.
If the type is not default constructible, std::array<T, N> ret;
won't work (at least, for N > 0
).
And if it's not copy assignable, then the fill
won't work either. (Also std::array
has a fill
member function.)
And finally, if it's not move constructible, then return ret;
won't work.