我需要存储前 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
但这仍然不是您要找的。p>
我不知道你是否可以制作 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/