未指定模板参数实例化C++模板引发无限递归的原因探究
模板递归实例化错误原因解析
先看你提供的无法编译的代码:
#include <iostream> #include <utility> template <int N> struct factorial { static const int value = N * factorial::value; // (*) }; template <> struct factorial<0> { static const int value = 1; }; int main() { constexpr int result = factorial<5>::value; std::cout << result; }
错误核心原因
标记(*)处的factorial::value会触发无限递归实例化,具体逻辑如下:
- 这里的
factorial没有指定模板参数,编译器不会将其判定为依赖名称,而是直接解析为当前正在实例化的模板特化——比如当实例化factorial<5>时,factorial就等同于factorial<5>。 - 计算
factorial<5>::value时,表达式展开为5 * factorial<5>::value,这又要求再次实例化factorial<5>来获取value,形成无限递归循环,最终触发编译器的模板实例化递归深度限制。
修正方式
要实现阶乘的递归计算,必须明确指定递归的下一级模板参数,把(*)处的代码修改为:
static const int value = N * factorial<N-1>::value;
这样实例化factorial<5>时会依次触发factorial<4>、factorial<3>……直到匹配到factorial<0>的特化(其value为1),递归到此终止。
内容的提问来源于stack exchange,提问作者Dean
相关产品推荐
相关产品推荐

