为什么g ++ 5.4不能编译这个编译时的素数代码?

Zet*_*eta 9 c++ templates compiler-errors compile-time-constant constexpr

#include<iostream>
using namespace std;

template<int N> class Prime
{ // generate N prime numbers at compile time
public:
    unsigned int arr[N]{};
    constexpr Prime() {
        int k=0;
        for(unsigned int i=2; k<N; i++) {
            bool isPrime = true;
            for(int j=0; j<k; j++) {
                if(arr[j] > i/2) break;
                if(i % arr[j] == 0) {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime) arr[k++] = i;
        }
    }
};
int main()
{
    Prime<50000> prime; // if 50000->5000, ok
    for(auto& a : prime.arr) cout << a << ' ';
}
Run Code Online (Sandbox Code Playgroud)

G ++无法编译此代码.它花了很多年时间尝试编译,使用大量内存,最后只是崩溃.

如果我将数字50000变小或者摆脱constexpr它,它就会编译.但我想使用更大的阵列来节省时间.

任何想法将不胜感激.

Tem*_*Rex 6

这是一项实施质量(QoI)问题.从标准草案

附件B(资料性附录)执行数量[限制]

1由于计算机是有限的,因此C++实现不可避免地受限于它们可以成功处理的程序的大小.每个实施都应记录已知的限制.本文档可引用存在的固定限制,说明如何根据可用资源计算变量限制,或者说固定限制不存在或未知.

2限制可能会限制包含下述数量或其他数量的数量.建议将每个数量后面的括号内的数字作为该数量的最小值.但是,这些数量仅是指导原则,不能确定合规性.

(2.38) - 递归constexpr函数调用[512].

(2.39) - 在核心常数表达式[1 048 576]内评估的完整表达式.

您的算法超出了核心常量表达式中计算的全表达式的限制.请注意,gcc确实超出了最低要求,因为你的循环缩放为1/2 * N^2和gcc编译它N = 5,000.我无法找到gcc记录的硬限制.不幸的是,与clang不同-fconstexpr-steps,你不能覆盖gcc的constexpr评估数量.

结论:向gcc提交性能报告或使用clang(您的示例为其编译).