В моих модульных тестах я хочу быстрый и (чистый sh) грязный способ присвоения значений массиву stati c -size C из initializer_list
. Я не полный зверь, поэтому я хочу static_assert
, чтобы размеры были одинаковыми. Я написал вспомогательную функцию set_array
для этого:
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];
}
с намерением использовать ее как set_array(foo, {1, 2, 3, 4});
с объявленным foo как int foo[4]
.
Я использую C ++ 17, поэтому std std::initializer_list<T>::size
является constexpr, но как только я пропущу список через вызов функции, я теряю привилегию рассматривать его как constexpr, поскольку не могу ограничить параметры функции как constexpr.
Такое ощущение, что должно быть простое решение, которого я не вижу. Конечно, я мог бы представить некоторые извращенные игры метапрограммирования, в которые я мог бы играть, чтобы закодировать размер в типе, но это простой маленький помощник, который должен делать вещи чистыми и читаемыми, и я не хочу go гадить.
Вопрос: Есть ли простое решение, или я должен просто жить с утверждением времени выполнения? (Да, я знаю, что если мне дадут простое решение, я буду чувствовать себя глупо из-за того, что не видел его сам.) Думаешь, я поступаю неправильно? Это нормально, я открыт для предложений и ценю критику.
Подробности: Для полноты излагаются ошибки компилятора и информация о версии. В Clang версии 8.0.0-3 (которая поставляется с Ubuntu clang-8) я получаю:
error: static_assert expression is not an
integral constant expression
static_assert(list.size() == N);
^~~~~~~~~~~~~~~~
И с G CC 8.3.0 я получаю похожую ошибку, дополнительно сообщая мне, что list
не является константным выражением.