Is there a good pattern that will let me use templates to generate a precomputed array from a given an element type, desired length, and custom function f(int index)
?
Consider this C-style implementation.
#define FORLIST_1(fOfi) (fOfi)(0)
#define FORLIST_2(fOfi) FORLIST_1(fOfi) , (fOfi)(1 )
#define FORLIST_3(fOfi) FORLIST_2(fOfi) , (fOfi)(2 )
#define FORLIST_4(fOfi) FORLIST_3(fOfi) , (fOfi)(3 )
//... And so on
// Toy example user-specified function which describes how to create the table
double genEntry(u32 i) {
return i == 0 ? 0 : std::log(i) / std::log(5);
}
// Generate a precomputed lookup table
// FORLIST_15 expands into genEntry(0), genEntry(1), genEntry(2), ...
const double lookupTable[16] = {
FORLIST_16(genEntry)
};
What is the cleanest way to do the same thing with templates? It has to allow me to specify the number of elements in the array and allow me to supply some kind of user function (index as the parameter). Functors, std::function
, lambda, function pointer, etc, are probably all acceptable ways to define the element generator.
I will probably want to explicit-instantiate the template once into an obj/lib so that the table itself is only defined once ever, as a linkable symbol instead of being recompiled into each .cpp file that includes the header.
With variadic template, you may do something like:
template <typename F, std::size_t ... Is>
auto
make_array(F f, std::index_sequence<Is...>)
-> std::array<std::decay_t<decltype(f(0u))>, sizeof...(Is)>
{
return {{f(Is)...}};
}
Note: decay_t
, index_sequence
and make_index_sequence
are C++14 but can be written in C++11.