Is it possible to generate an array at compile time, like in this nice answer of G. Fritzsche: Georg Fritzsche
but with floating point values?
It wasn't possible in standard-compliant C++ when Georg wrote his answer, but with C++11 we can now do compile-time computation with floating-point and other numeric types.
The trick is to use constexpr
functions instead of non-type template parameters.
Here is a solution creating an array of double
s which takes an initialization class to map an int
index to a suitable value. The example create an array with 20 value approximating sin(x) for 20 values in the range [0, 2π]. Most of the code is devoted to producing a sequence of integers [0...N): if that operation is readily available, the code becomes fairly trivial (it is being added to C++14; see n3493).
#include <iostream>
#include <cmath>
template <int...> struct indices {};
template <int N, typename> struct make_list;
template <int... Indices>
struct make_list<0, indices<Indices...> > {
typedef indices<0, Indices...> type;
};
template <int N, int... Indices>
struct make_list<N, indices<Indices...> > {
typedef typename make_list<N-1, indices<N, Indices...> >::type type;
};
template <typename Init, int N, typename> struct array_aux;
template <typename Init, int N, int... Indices>
struct array_aux<Init, N, indices<Indices...> >
{
static double const values[N];
};
template <typename Init, int N, int... Indices>
double const array_aux<Init, N, indices<Indices...> >::values[N] = {
Init::value(Indices)...
};
template <typename Init, int N>
struct array
: array_aux<Init, N, typename make_list<N-1, indices<> >::type>
{
};
struct init_sin
{
static constexpr double value(int index) {
return std::sin(index * 2.0 * 3.1415 / 20.0);
}
};
int main()
{
for (int i = 0; i != 20; ++i) {
std::cout << array<init_sin, 20>::values[i] << "\n";
}
}
If the generator function, i.e., Init::value()
is a constexpr
function actually return constant values (probably not quite the case for std::sin()
) the values can be computed at compile time. Otherwise they will be computed during static initialization.