static compile time table with floating point values

前端 未结 2 325
你的背包
你的背包 2021-01-14 21:38

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?

相关标签:
2条回答
  • 2021-01-14 22:02

    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.

    0 讨论(0)
  • 2021-01-14 22:18

    Here is a solution creating an array of doubles 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.

    0 讨论(0)
提交回复
热议问题