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

C++ why my template expansion lead to compiler stack overflow?

我正在尝试模板元编程并编写一个函数来计算 base^re 的幂,例如 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 都崩溃了。我哪里错了? 谢谢

解决方案: 你必须专门化你的模板,使 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?...

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

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

要解决此问题,您需要专门 N = 0 情况下的函数。