模板元编程递归上限

Template metaprogramming recursion up limits?

本文关键字:递归 编程      更新时间:2023-10-16

我正在编写一个非常简单的模板类,使用元编程在编译时计算sum,如下所示:

#include <iostream>
using namespace std;
template<int N>
class Sum
{
    public:
        enum {value = N + Sum<N-1>::value };
};
template<>
class Sum<0>
{
    public:
        enum {value = 0};
};

int main()
{
    cout << Sum<501>::value << endl;
}

有趣的是:

  • 当我打印Sum<500>及以下,效果良好
  • 当涉及到Sum<501>,编译失败,返回:

    sum.cpp:9:从Sum<500>' sum.cpp:9: instantiated from sum<501>'sum.cpp:22:从这里实例化

    sum.cpp:9:错误:不完整的类型Sum<1>' used in nested name specifier sum.cpp:9: error: enumerator value for值"不是整数"恒定

  • 总和<501>将报告Sum<1> ,总和<502>将报告Sum<2> ,差总是2,在我看来编译器的资源限制为500。

你知道吗?他们有办法打破这种限制吗?

谢谢。

编辑:
谢谢大家,重点不是算法,而是编译器的限制——我知道有一种简单的方法可以得到总和:)

第2版:

  • 使用gcc 4.6+,错误消息会更有帮助

    sum.cpp:9:14:错误:模板实例化深度超过最大值1024(使用-ftemplate depth=增加最大值)实例化'类总和<1> 'sum.cpp:9:14:从递归实例化'总和<1024>'sum.cpp:9:14:从'sum<1025>'sum.cpp22:22:22:从这里实例化

所以是的,使用ftemplate深度是正确的方法。但在窗户里怎么样?VC9.0的上限是499,似乎没有设置模板深度的选项,请参阅此处的

如果使用GCC,可以使用-ftemplate-depth=X设置模板递归深度,其中X是所需深度:

g++ ...... -ftemplate-depth=750

请记住,这不仅仅是你可以任意设定的某个限制。在某个时刻,您将遇到操作系统和硬件的限制。

关于实际的和函数,有一个众所周知的前N个正整数的和的解析解。

(即n*(n+1)/2

附录B规定了建议的最低限值;对于递归嵌套的模板实例化,建议的最小限制为1024。你的执行似乎有500的限制;这仍然是符合的,因为建议的最低限度只是指导原则。

您的编译器可能有一个命令行标志或其他选项来增加其递归嵌套模板实例化限制。

最简单的解决方法是使用非递归算法;在你的情况下,

template<int N>
class Sum
{
    public:
        enum {value = N * (N + 1) / 2 };
};