是否可以在编译时评估数组? [英] Is it possible to evaluate array on compilation time?

查看:84
本文介绍了是否可以在编译时评估数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要存储前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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆