【发布时间】: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<N>::value替换为N * (N + 1) / 2来解决此特定问题。 -
GCC 有一个选项,-ftemplate-depth,它改变了递归限制。我只能假设其他编译器有类似的选项
-
我建议你看看我的answer 这里,我一开始遇到了同样的问题,但通过分而治之的方式解决了这个问题。
-
@Xeo 谢谢,但我不是在寻找解决计算总和的问题,而是想办法扩大限制,现在我知道对于 gcc 我们可以使用 ftemplate-depth,但不要不知道在windows for vc++中怎么做
-
我的回答显示了一种使默认限制成为非问题的方法。
标签: c++ templates template-meta-programming