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

C++ 是否有更好的方法通过模板用预先计算的值填充数组(用于运行时)?,c++,templates,c-preprocessor,C++,Templates,C Preprocessor,因此,假设我有一个模板结构函数fib::value。我想在运行时得到第n个斐波那契数。为此,我创建了数组fibs[]={fib::value,…,fib::value}。不幸的是,对于某些函数,maxN可能非常大,我不能只用手来填充它。所以我编写了一些预处理器指令,以使任务更简单 #define fib(x) (fib<(x)>::value) #define fibLine_level_0(x) fib(5*(x) + 0), fib(5*(x) + 1), fib(5*(x) +

因此,假设我有一个模板结构函数
fib::value
。我想在运行时得到第n个斐波那契数。为此,我创建了数组
fibs[]={fib::value,…,fib::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]))
定义fib(x)(fib::value) #定义fibLine_级别_0(x)fib(5*(x)+0)、fib(5*(x)+1、fib(5*(x)+2、fib(5*(x)+3、fib(5*(x)+4) #定义fibLine\u level\u 1(x)fibLine\u level\u 0(2*(x)+0),fibLine\u level\u 0(2*(x)+1) #定义fibLine\u level\u 2(x)fibLine\u level\u 1(2*(x)+0),fibLine\u level\u 1(2*(x)+1) #定义fibLine\u level\u 3(x)fibLine\u level\u 2(2*(x)+0),fibLine\u level\u 2(2*(x)+1) #定义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;
intfibs[]={fibLine_level_3(0)};
对于(int i=0;icout
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;
};

您只需提供生成«函数»(我们的
fibstruct)的
generate_array

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;
};

你只需要用生成函数“.<代码> > FiB结构”提供<<代码> GuangyTyAs/<代码> .< /P> < P>谢谢“无名”,给出问题的链接,在这里我发现了McCeleldReon为简单C++(没有新的特性)。我使用它并根据自己的需要进行扩展

所以,这个概念很简单,但有点奇怪。我们必须生成递归模板结构,其中第一个字段是与其他参数相同的模板结构

template<size_t N>
struct FibList {
    FibList<N-1> previous;
    size_t value;
    FibList<N>() : value(fib<N>::value) {}
};
注意,交换
FibList
FibList
的位置将在编译器中产生堆栈溢出

我们必须解决另一个问题——模板递归的深度有限(取决于编译器和/或选项)。但幸运的是,编译器只有深度限制,而没有模板的内存限制(嗯,是的,内存限制比深度限制更大)。因此,我们有一个明显的丑陋的解决方案-调用
fib
,并以等于深度限制的步长串联-我们永远不会捕捉到关于
fib
的模板深度限制。但我们不能只在运行时编写
fib::value
。所以我们得到了解决方案——编写宏,使用
fib::value
专门化
FibList

#define SetOptimizePointForFib(N) template<>\
struct FibList<N> {\
    FibList<(N)-1> previous;\
    size_t value;\
    FibList<N>() : value(fib<N>::value) {}\
};

所以我们得到了编译时间的预处理和填充静态长度的数组。

谢谢“无名”,给出了问题的链接,我在这里找到了@ McCeleldReon的简单C++(没有新的特性)。我使用它并根据自己的需要进行扩展

所以,这个概念很简单,但有点奇怪。我们必须生成递归模板结构,其中第一个字段是与其他参数相同的模板结构

template<size_t N>
struct FibList {
    FibList<N-1> previous;
    size_t value;
    FibList<N>() : value(fib<N>::value) {}
};
注意,交换
FibList
FibList
的位置将在编译器中产生堆栈溢出

我们必须解决另一个问题——模板递归的深度有限(取决于编译器和/或选项)。但幸运的是,编译器只有深度限制,而没有模板的内存限制(嗯,是的,内存限制比深度限制更大)。因此,我们有一个明显的丑陋的解决方案-调用
fib
,并以等于深度限制的步长串联-我们永远不会捕捉到关于
fib
的模板深度限制。但我们不能只在运行时编写
fib::value
。所以我们得到了解决方案——编写宏,使用
fib::value
专门化
FibList

#define SetOptimizePointForFib(N) template<>\
struct FibList<N> {\
    FibList<(N)-1> previous;\
    size_t value;\
    FibList<N>() : value(fib<N>::value) {}\
};

因此,我们得到了真正的编译时precalc和填充长度惊人的静态数组。

如果可能的话,在编译时计算斐波那契数的
constepr
函数可能会更干净一些。编辑:看起来@ipc可能有相同的想法。有几个重复的。。。您可以使用boost预处理器。你可以使用可变模板创建一个constepr std::array。这段代码必须在运动编程中使用,这意味着:没有boost,也可能没有C++11好吧,让我们假设有C++11(只是因为C++11很酷),但我更喜欢用C++11中较旧版本的语言来回答。在C++11中,你可以使用可变索引来生成数组。如果可能的话,用于在编译时计算斐波那契数的
constepr
函数可能会更简洁一些。编辑:看起来@ipc可能有相同的想法。有几个重复的。。。您可以使用boost预处理器。你可以使用可变模板创建一个constexpr std::array。这段代码必须在运动编程中使用,这意味着:没有boost,也可能没有C++11好吧,让我们假设有C++11(因为C++11很酷),但我更喜欢用C++11语言的旧版本来回答。在C++11中,你可以使用可变索引来生成数组。我没有要求重写fib,我请求帮助生成数组。现在我没有访问C++11编译器的权限,并且ideone.com也不支持它(甚至是constexpr)。我将您的答案标记为正确,但是:1)这仅适用于C++11。2) 您遇到了“模板实例化深度超过最大值”的问题。我根据你提供的链接中的其他答案写下了自己的答案,你可以在下面看到。我没有要求重写fib,我要求帮助生成数组。现在我没有访问C++11编译器的权限,并且ideone.com也不支持它(甚至是constexpr)。我将您的答案标记为正确,但是:1)这仅适用于C++11。2) 您遇到了“模板实例化深度超过最大值”的问题。我根据你们提供的链接中的其他答案写下了自己的答案,你们可以在下面看到。
size_t *fibArray = reinterpret_cast<size_t*>(&fibList);
// start point
template<>
struct FibList<0> {
    size_t value;
    FibList<0>() : value(0) {}
};

// start point
template<>
struct FibList<1> {
    FibList<0> previous;
    size_t value;
    FibList<1>() : value(1) {}
};
#define SetOptimizePointForFib(N) template<>\
struct FibList<N> {\
    FibList<(N)-1> previous;\
    size_t value;\
    FibList<N>() : value(fib<N>::value) {}\
};
SetOptimizePointForFib(500);
SetOptimizePointForFib(1000);
SetOptimizePointForFib(1500);
SetOptimizePointForFib(2300);