递归模板实例化超过最大深度256

The*_*ask 9 c++ recursion templates clang c++11

我试图使用constexpr函数重写Factorial实现但由于某种原因我不知道为什么我得到编译错误:

递归模板实例化超过最大深度256

实际上我知道错误信息意味着什么,但我不知道为什么我得到这个错误以及为什么代码1使用struct工作但第二个使用函数没有.他们之间有什么区别?

 // yes, I know it doesn't return the factorial value. First I want to make it compile
template <int N>
constexpr int f2()
{
    return N == 0 ? 1 : f2<N - 1>();
}

template <int N> struct Factorial
{
    enum 
    {
        value = N * Factorial<N - 1>::value
    };
};

template <> struct Factorial<0>
{
    enum
    {
        value = 1
    };
};


int main() 
{
    x = f2<4>(); // compile error
    n = Factorial<4>::value; // works fine
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*our 6

你需要一个像下面这样的停止状态:

template <>
int f2<0>()
{
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

既然f2<N - 1>()必须实例化,那么你的另一种情况就是停止状态:

template <> struct Factorial<0>
Run Code Online (Sandbox Code Playgroud)

但是如果你正在使用constexpr你根本不需要使用模板,因为重点是它将在编译时完成,所以把它变成这样:

constexpr int f2(int n)
{
  return n == 0 ? 1 : (n * f2(n-1));
}
Run Code Online (Sandbox Code Playgroud)


JKo*_*Kor 5

当 时N == 0,编译器仍然必须实例化,f2<-1>因为代码中存在函数调用。什么时候f<-1>被实例化,f<-2>被实例化等等。一次又一次地应用这个语句,编译器将继续通过模板递归,直到它超过最大深度。