【问题标题】:Template metaprogramming recursion up limits?模板元编程递归上限?
【发布时间】:2012-08-29 22:54:01
【问题描述】:

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

#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 及以下时,它工作正常
  • 当涉及到 Sum 时,编译失败:

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

    sum.cpp:9: 错误:不完整类型 Sum<1>' used in nested name specifier sum.cpp:9: error: enumerator value forvalue' 不是整数 常数

  • Sum会报Sum的错误,Sum会报Sum的错误,差总是2,在我看来编译器有500的限制资源.

对此有任何想法吗?他们是打破这个限制的方法吗?

谢谢。

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

编辑2:

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

    sum.cpp:9:14: 错误:模板实例化深度超过最大值 1024(使用-ftemplate-depth=增加最大值)实例化 ‘class Sum’ sum.cpp:9:14: 从递归实例化 ‘Sum’ sum.cpp:9:14: 从 ‘Sum’ 实例化 sum.cpp:22:22: 从这里实例化

所以是的,使用 ftemplate-depth 是正确的方法。但是在 Windows 中呢? VC9.0 的上限是 499,似乎没有设置模板深度的选项,请参阅here

【问题讨论】:

  • 当然,任何现实世界的计算机程序,包括你的编译器,都有它所能做的有限的限制。您可以通过将Sum&lt;N&gt;::value 替换为N * (N + 1) / 2 来解决此特定问题。
  • GCC 有一个选项,-ftemplate-depth,它改变了递归限制。我只能假设其他编译器有类似的选项
  • 我建议你看看我的answer 这里,我一开始遇到了同样的问题,但通过分而治之的方式解决了这个问题。
  • @Xeo 谢谢,但我不是在寻找解决计算总和的问题,而是想办法扩大限制,现在我知道对于 gcc 我们可以使用 ftemplate-depth,但不要不知道在windows for vc++中怎么做
  • 我的回答显示了一种使默认限制成为非问题的方法。

标签: c++ templates template-meta-programming


【解决方案1】:

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

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

请记住,这不仅仅是您可以任意设置的一些限制。在某些时候,您会遇到操作系统和硬件限制。

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

(即n*(n+1)/2

【讨论】:

    【解决方案2】:

    附件 B 规定了建议的最低限度;对于递归嵌套模板实例,建议的最小限制为 1024。您的实现似乎有 500 的限制;这仍然是合规的,因为建议的最低限度只是指导方针。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      相关资源
      最近更新 更多