C ++为什么我的模板扩展会导致编译器堆栈溢出?

时间:2017-02-20 10:23:40

标签: c++ templates meta expand

我正在尝试模板元编程并编写函数来计算基数的函数,如3 ^ 2 = 9

template<int N>
int Tpow(int base){return N==0?1:base*Tpow<N-1>(base);}
int main()
{
    int r3=Tpow<3>(2);
    return 0;
}

只是几行,但它崩溃了gcc和clang。我哪里弄错了? 感谢。

2 个答案:

答案 0 :(得分:3)

解决方案:您必须将模板专门化为N等于0.赞:

template<>
int Tpow<0>(int base){return 1;}

现在您已经拥有了这个,您也可以像这样优化原始模板:

template<int N>
int Tpow(int base){return base*Tpow<N-1>(base);}

因为你知道你处理N等于0的情况。

说明:您的编译器基本上是这样做的:它看到了

int r3=Tpow<3>(2);

并为3创建一个函数作为模板变量,如此

int Tpow_3(int base){return 3==0?1:base*Tpow<3-1>(base);}

然后它需要为2创建一个函数作为模板变量,如此

int Tpow_2(int base){return 2==0?1:base*Tpow<2-1>(base);}

然后继续,因为编译器不关心你的0==0?...

答案 1 :(得分:1)

编译器必须编译整个函数体:它不能依赖于三元条件只能编译一面。所以递归没有阻塞。

(使用C ++ 11的constexpr也无济于事。)

要解决此问题,您需要专门化 N = 0案例的函数。