编译时间递归和条件

bar*_*s.m 9 c++ compile-time

我正在阅读"打印1到1000没有循环或条件"的响应,我想知道为什么有必要在最佳答案中使用NumberGeneration <1>的特殊情况.

如果我删除它并在模板中添加N == 1的检查(下面的代码),代码将无法编译"模板实例化深度超过最大值",但我不确定原因.条件在编译时是否处理不同?

#include <iostream>

template<int N>
struct NumberGeneration
{
    static void out(std::ostream& os)
    {
        if (N == 1)
        {
            os << 1 << std::endl;
        }
        else
        {
            NumberGeneration<N-1>::out(os);
            os << N << std::endl;
        }
    }
};

int main()
{
    NumberGeneration<1000>::out(std::cout);
}
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 12

代码生成和编译不依赖条件分支!考虑一下:

// don't declare bar()!

void foo()
{
     if (false) { bar(); }
}
Run Code Online (Sandbox Code Playgroud)

如果你从未声明bar(),这是一个编译错误,即使永远无法达到内部范围.出于同样的原因,NumberGeneration<N-1>总是被实例化,无论是否可以到达该分支,并且您具有无限递归.

实际上,条件的静态模拟恰好是模板特化:

template <> struct NumberGeneration<0> { /* no more recursion here */ };
Run Code Online (Sandbox Code Playgroud)

  • @ baris.m:但是"达到代码"的含义是一个至关重要的微妙之处:在编译器编译过程中,它始终是一次,在程序执行期间再次*有条件地*在运行时. (2认同)