Я хотел бы преобразовать значение времени выполнения int v
в вызов соответствующей функции с нетипичным параметром шаблона v
, например, template <int v> void hello()
.
Вот способ грубой силызаписывая это:
using fn_type = void();
template <int v>
void hello() {
// of course ITRW this function requires v to be a
// constexpr value
printf("hello: %d\n", v);
}
static std::array<fn_type *, 3> lut = {
hello<0>,
hello<1>,
hello<2>
};
void hello_dispatch(int v) {
lut[v](); // we don't handle OOB values b/c we are naughty like that
}
Я могу жить с этим для 3 значений, но это становится непрактичным с большим количеством значений, или когда сам предел вычисляется из некоторого другого значения времени компиляции.
Как можно инициализировать LUT 2 во время компиляции без явного перечисления различных экземпляров hello<0>, hello<1>, ...
в инициализаторе?
Вот что я придумал:
template <size_t I, size_t MAX>
constexpr void make_helper(std::array<fn_type *, MAX>& a) {
if constexpr (I < MAX) {
a[I] = hello<I>;
make_helper<I + 1, MAX>(a);
}
}
template <size_t MAX>
constexpr std::array<fn_type *, MAX> make_lut() {
std::array<fn_type *, MAX> ret{};
make_helper<0, MAX>(ret);
return ret;
}
static constexpr std::array<fn_type *, 3> lut2 = make_lut<3>();
Должно быть что-то более простое, лучшее и более идиоматическое в C ++ 17 - в частности, без необходимости рекурсии.
2 Или, если этопроблема XY, как я могу реализовать hello_dispatch
без LUT (но, по крайней мере, с эффективностью LUT).