编译模板时的无限循环

Infinite loop while compiling template

本文关键字:无限循环 编译      更新时间:2023-10-16

为什么这门课程编译器要去无限循环。我正在使用Visual Studio 2012(编译器VC++11(。

template <unsigned N, unsigned To = N - 1>
struct is_prime
{
    static const bool value = (N % To != 0) && is_prime<N, To - 1>::value;
};
template <unsigned N>
struct is_prime<N, 1>
{
    static const bool value = true;
};
template <unsigned N>
struct is_prime<N, 0>
{
    static const bool value = false;
};
template <unsigned N>
struct next_prime
{
private:
    static const unsigned n_plus_one = N + 1;
public:
    static const unsigned value = is_prime<n_plus_one>::value ? n_plus_one : next_prime<n_plus_one>::value;
};
int main()
{
    cout << is_prime<5>::value << endl;   //Compiles. true.
    cout << is_prime<4>::value << endl;   //Compiles. false.
    cout << next_prime<4>::value << endl; //Infinite compiler loop.
    return 0;
}

如果我写没有成员valuenext_prime<100>专业化:

template <>
struct next_prime<100>
{
};

我会看到编译器错误。那么,为什么还要尝试编译呢?

因为它计算next_prime<4>::value

template <unsigned N>
struct next_prime {
// ...
static const unsigned n_plus_one = N + 1;
// ...
static const unsigned value = is_prime<n_plus_one>::value ? n_plus_one : next_prime<n_plus_one>::value;

在上述next_prime<n_plus_one>::value中,只有在is_prime<n_plus_one>::value false时才能实例化。

您可以使用返回其中一种类型的std::conditional<>修复它,具体取决于条件:

template <unsigned N>
struct next_prime : std::conditional<
      is_prime<N + 1>::value
    , std::integral_constant<unsigned, N + 1> // not instantiated here
    , next_prime<N + 1>                       // not instantiated here
    >::type                                   // instantiated here
{};