【问题标题】:C++ why my template expansion lead to compiler stack overflow? [duplicate]C++ 为什么我的模板扩展导致编译器堆栈溢出? [复制]
【发布时间】:2017-07-09 13:55:57
【问题描述】:

我正在尝试模板元编程并编写一个函数来计算 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 都会崩溃。我哪里做错了? 谢谢。

【问题讨论】:

  • 标记为重复。尽管另一个问题涉及constexpr 而这不是,但潜在的误解是相同的。

标签: c++ templates meta expand


【解决方案1】:

解决方案:您必须将模板专门化为 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?...

【讨论】:

  • int 应改为unsigned int
【解决方案2】:

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

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

要解决这个问题,您需要专门化 N = 0 情况的函数。

【讨论】:

  • 但是,C++17 的if constexpr 应该会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 2010-09-11
  • 2012-01-19
  • 2018-07-01
  • 2011-10-22
  • 1970-01-01
  • 2016-02-28
相关资源
最近更新 更多