只是向TMPing介绍自己,并遇到了一个怪癖

Jus*_*ten 4 c++ templates metaprogramming c1001

我只是想学习初学者的语法,以及当我在VS2008中编写这么短的代码时它是如何工作的.下面的代码用于添加数字1到499,但如果我添加1到500,编译器错误给我:

fatal error C1001: An internal error has occurred in the compiler.

而我只是想知道为什么会这样.编译器可以生成多少代码或者某些东西是否有一些限制,它恰好是我的一个很好的整数500?

#include <iostream>
using namespace std;

template < int b >
struct loop {
    enum { sum = loop< b - 1 >::sum + b };
};

template <>
struct loop< 0 > {
    enum { sum = 0 };
};

int main() {
    cout << "Adding the numbers from 1 to 499 = " << loop< 499 >::sum << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Yac*_*oby 5

我假设使用gcc(以及扩展名为g ++),默认的最大模板递归深度500至少在我的机器上,我设法使用(略微更好)的警告消息重现您的问题.编译loop<500>::sum工作正常,但尝试编译loop<501>::sum失败.

如果您正在使用gcc(或g ++),解决方案是使用-ftemplate-depth-##(其中##是允许的最大深度)进行编译.

因此,例如main.cpp使用最大模板递归深度2000 进行编译

g++ -ftemplate-depth-2000 main.cpp
Run Code Online (Sandbox Code Playgroud)

或者将代码转换为:

template < int b >
struct loop {
    enum { sum = (b*(b+1))/2 };
};
Run Code Online (Sandbox Code Playgroud)

(但我承认上面的代码不能帮助你学习模板元编程)


sbi*_*sbi 5

VC9(VS2008)崩溃,数字> 499.代码本身有效,甚至允许编译器在一定量的递归实例化后停止编译,从而提供诊断.但是,内部编译器错误(通俗也称为ICE)肯定不是一个很好的诊断.

ICE始终是编译器的错误.它也可能是由代码中的错误引起的,但如果是这种情况,则编译器无法显示该错误的正确诊断.如果错误是可重现的,您应该向编译器供应商提交错误报告,以便他们可以修复错误.

报告此类错误(此处或其他地方)时,您应该永远不会提供您使用的确切编译器版本.