c++ - 是否可以在编译时评估数组?

标签 c++ algorithm c++11 constexpr

我需要存储前 N 个斐波那契数列。

const int N = 100;
long long int fib[N] = {0};
fib[0] = 1;
fib[1] = 1;
for(int i = 2; i < N; ++i)
    fib[i] = fib[i-2] + fib[i-1];
return 0;

是否可以制作fib[] constexpr,并以某种方式在编译时对其求值?

最佳答案

首先,您必须在编译时版本中编写斐波那契算法,因此请考虑以下内容:

template <size_t N>
struct Fibo {
    static constexpr const size_t value {Fibo<N-2>::value + Fibo<N-1>::value};
};

template <>
struct Fibo<0> {
    static constexpr const size_t value {1};
};

template <>
struct Fibo<1> {
    static constexpr const size_t value {1};
};

你可以像那样简单地使用它:

std::cout << Fibo<0>::value << std::endl;
std::cout << Fibo<1>::value << std::endl;
std::cout << Fibo<2>::value << std::endl;
std::cout << Fibo<3>::value << std::endl;
std::cout << Fibo<10>::value << std::endl;
std::cout << Fibo<50>::value << std::endl;

输出值为:

1
1
2
3
89
20365011074

但这仍然不是您要找的。

我不知道你是否可以制作 constexpr 数组(但可能有这种可能性),但你可以做一些稍微不同的事情。考虑:

template <size_t N>
struct Storage {
    static size_t data[N+1];
};

template <size_t N> size_t Storage<N>::data[N+1] {};

template <size_t N, size_t F>
struct Filler {
    static constexpr void fill () {
        Storage<N>::data[F] = Fibo<F>::value;
        Filler<N, F-1>::fill ();
    }
};

template <size_t N>
struct Filler<N, 0> {
    static constexpr void fill () { 
        Storage<N>::data[0] = Fibo<0>::value;
    }
};

template <size_t N>
struct Calc {
    static constexpr void calc () {        
        Filler<N, N>::fill ();
    }
};

用法是这样的:

constexpr const size_t N = 12;

Calc<N>::calc ();
size_t* ptr = Storage<N>::data;

for (int i = 0; i <= N; ++i) {
    std::cout << ptr[i] << std::endl;
}

和输出:

1
1
2
3
5
8
13
21
34
55
89
144
233

这里重要的是 Storage类,它用适当数量的元素存储我们的数组。

一般 Filler类(带有两个模板参数)用于任何 F可以传递的值,0 值除外。因为如果我们到达 0 索引,我们不想再次调用 fill()成员函数,因为我们完成了。这就是为什么 Filler 部分特化的原因类存在。

希望我能帮上忙。

关于c++ - 是否可以在编译时评估数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35389493/

相关文章:

C++:有符号 64 位整数中两个无符号 64 位整数的差

c++ - 在 C++ 中使用类层次结构时是否应该避免向下转型?

javascript - 查找特定周长内的坐标的最快方法是什么?

C++ std::tr1::hash::operator() 未定义?

c++ - 匹配 bool vs const void* 重载的函数的地址

c++ - 使用可变参数 lambda 迭代可变参数函数模板的参数

c++ - 使用复杂数据结构时内存泄漏( vector 数组的数组)

algorithm - 如何使用 boost 将复杂的多边形划分为简单的多边形?

algorithm - 比较Canny算法的轮廓结果和相似度

C++ 反射指南/教程