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 情况下的函数。
我正在尝试模板元编程并编写一个函数来计算 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 情况下的函数。