c++ - 有没有更好的方法来通过模板用预先计算的值填充数组(用于运行时)?

标签 c++ templates c-preprocessor

所以,假设我有一个模板结构函数 fib<i>::value .我想在运行时获得第 n 个斐波那契数。为此,我创建了数组 fibs[] = { fib<0>::value, ... , fib<maxN>::value } .不幸的是,对于某些功能maxN可以很大,我不能只用手填满它。所以我写了一些预处理器指令来简化任务。

#define fib(x) (fib<(x)>::value)
#define fibLine_level_0(x) fib(5*(x) + 0), fib(5*(x) + 1), fib(5*(x) + 2), fib(5*(x) + 3), fib(5*(x) + 4)
#define fibLine_level_1(x) fibLine_level_0(2*(x) + 0), fibLine_level_0(2*(x) + 1)
#define fibLine_level_2(x) fibLine_level_1(2*(x) + 0), fibLine_level_1(2*(x) + 1)
#define fibLine_level_3(x) fibLine_level_2(2*(x) + 0), fibLine_level_2(2*(x) + 1)

#define cAarrSize(x) (sizeof(x) / sizeof(x[0]))

我是这样用的:

int fibs[] = { fibLine_level_3(0) };

for (int i = 0; i < cAarrSize(fibs); i++)
    cout << "fib(" << i << ") = " << fibs[i] << endl;

您可能需要的代码:

template<int i>
struct fibPair{
    static const int fst = fibPair<i-1>::snd;
    static const int snd = fibPair<i-1>::fst + fibPair<i-1>::snd;
};

template<>
struct fibPair<0> {
    static const int fst = 0;
    static const int snd = 1;
};

template<int i>
struct fib {
    static const int value = fibPair<i>::fst;
};

但是这段代码真的很难看。怎么做才能更漂亮?

限制条件:此代码必须用于体育节目。这意味着 - 没有第三方库,有时也没有 C++11(但它可以)

最佳答案

Fib结构可以重写如下:

template <size_t i>
struct fib
{
    static const size_t value = fib<i - 1>::value + fib<i - 2>::value;
};

template <>
struct fib<0>
{
    static const size_t value = 0;
};

template <>
struct fib<1>
{
    static const size_t value = 1;
};

可以使用 C++11 计算斐波那契数的编译时数组。

编辑 1(更改了 fib 值的类型)。

编辑 2:

编译时生成斐波那契数列(基于 this 答案)。

template<unsigned... args> struct ArrayHolder
{
    static const unsigned data[sizeof...(args)];
};

template<unsigned... args>
const unsigned ArrayHolder<args...>::data[sizeof...(args)] = { args... };

template<size_t N, template<size_t> class F, unsigned... args>
struct generate_array_impl
{
    typedef typename generate_array_impl<N-1, F, F<N>::value, args...>::result result;
};

template<template<size_t> class F, unsigned... args>
struct generate_array_impl<0, F, args...>
{
    typedef ArrayHolder<F<0>::value, args...> result;
};

template<size_t N, template<size_t> class F>
struct generate_array
{
    typedef typename generate_array_impl<N-1, F>::result result;
};

int main()
{
    const size_t count = 10;
    typedef generate_array<count, fib>::result fibs;

    for(size_t i = 0; i < count; ++i)
        std::cout << fibs::data[i] << std::endl;
}

您只需为 generate_array 提供生成 «function»(我们的 fib 结构)。

关于c++ - 有没有更好的方法来通过模板用预先计算的值填充数组(用于运行时)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14542572/

相关文章:

c++ - 模板别名冲突类型。 g++ 编译成功而 clang 失败

c - 标准库包含多个文件多次?

c++ - 错误 : Vector subscript out of range. 第 1201 行

c++ - 将整数列表解析为 vector 或映射或多映射?

c++ - 如何从 lambda 中的函数返回?

c++ - 如何检查模板的参数类型是否完整?

c++ - 如何在 Visual Studio 2008 中为我的应用程序设置图标?

c++ - 访问 ctor 中的私有(private)类内存

c - 允许使用什么类型的内容作为 C 预处理器宏的参数?

c++ - ##(双哈希)在预处理器指令中起什么作用?