是否可以在编译时评估数组? [英] Is it possible to evaluate array on compilation time?
问题描述
我需要存储前N个斐波那契数字的数组。
I need to store the array of first N Fibonacci numbers.
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,并对其进行评估
Is it possible to make fib[] constexpr, and evaluate it at compilation time somehow ?
推荐答案
首先,您必须在编译时版本中编写Fibonacci算法,因此请考虑以下内容:
First of all you have to write Fibonacci algorithm in compile time version, so consider following:
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};
};
,您可以这样简单地使用它:
and you can use this as simply as that:
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
但这仍然不是您想要的。
But this is still not you are looking for.
我不知道您是否可以创建constexpr数组(但是也许有可能),但您可以做些微的不同。考虑:
I do not know if you can make constexpr array (but probably there is a possibility), but you can do it slightly different. Consider:
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
类,用于存储具有适当数量的元素的数组。
What is important here is the Storage
class which stores our array with appropriate number of elements.
常规 Filler
类(带有两个模板参数)用于任何可以传递的 F
值,但值0除外。因为我们到达0索引,我们不想再次调用 fill()
成员函数,因为已经完成了。所以这就是为什么 Filler
类存在部分专业化的原因。
General Filler
class (with two template parameters) is used for any F
value that can be passed, except value of 0. Because if we reach the 0 index, we don't want to call once again fill()
member function, because we are done. So that's the reason why partial specialization of Filler
class exists.
希望我可以帮上忙。
这篇关于是否可以在编译时评估数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!