Search code examples
c++templates

std::array filling using std::fill vs std::integer_sequence


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});

Solution

  • 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.