In my unit tests, I want a quick and (cleanish) dirty way to assign values to a static-size C-array from an initializer_list. I'm not a complete beast, so I want to static_assert that the sizes are the same. I wrote a helper function set_array to do this:
template <typename T, std::size_t N>
constexpr void set_array(T (&x)[N], std::initializer_list<T>&& list) {
assert(list.size() == N); // why can't I static_assert in C++17?
for (std::size_t i = 0; i < N; ++i)
x[i] = list.begin()[i];
}
with the intention of using it as set_array(foo, {1, 2, 3, 4}); with foo declared like int foo[4].
I'm using C++17, so std std::initializer_list<T>::size is constexpr, but as soon as I pass the list through a function call, I lose the privilege of treating it as constexpr since I can't constrain the function parameters to be constexpr.
This feels like it should have a simple solution that I'm not seeing. Sure, I could imagine some perverse metaprogramming games I could play to encode the size in a type, but this is a simple little helper that's supposed to make things clean and readable, and I don't want to go nuts.
Question: Is there a simple solution, or should I just live with the runtime assert? (Yes, I know that if I'm given a simple solution, I'm going to feel stupid for not having seen it myself.) Think I'm going about it the wrong way? That's fine, I'm open to suggestions and appreciate the criticism.
Details: For completeness, here is the compiler error and version info. In Clang version 8.0.0-3 (That comes with Ubuntu clang-8) I get:
error: static_assert expression is not an
integral constant expression
static_assert(list.size() == N);
^~~~~~~~~~~~~~~~
And with GCC 8.3.0 I get a similar error, additionally telling me that list is not a constant expression.