具有浮点值的静态编译时间表

时间:2013-12-04 22:44:54

标签: c++ templates c++11 static variadic-templates

是否有可能在编译时生成一个数组,就像这个G.Fritzsche的好答案一样: Georg Fritzsche

但是有浮点值吗?

我认为以这种方式不可能,因为递归发生的可变扩展需要编译时const值吗?

是否有另一种生成编译时浮点数组的方法,元函数在编译时计算复杂的东西,或者仅限于整数类型的算术?

感谢您的投入! : - )

2 个答案:

答案 0 :(得分:3)

当Georg写下他的答案时,在符合标准的C ++中是不可能的,但是使用C ++ 11,我们现在可以使用浮点和其他数字类型进行编译时计算。

诀窍是使用constexpr函数而不是非类型模板参数。

答案 1 :(得分:3)

这是一个创建double数组的解决方案,它采用初始化类将int索引映射到合适的值。该示例创建一个数组,其值为 sin(x),其值为 [0,2π] 范围内的20个值。大多数代码专门用于生成整数序列 [0 ... N):如果该操作随时可用,则代码变得相当简单(它被添加到C ++ 14;见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";
    }
}

如果生成器函数,即Init::value()constexpr函数实际返回常量值(可能不是std::sin()的情况),则可以在编译时计算这些值。否则,它们将在静态初始化期间计算。