Say, I have a constexpr
variable that contains all primes less than 216.
constexpr auto primes = [] {
constexpr int N = 1 << 16;
std::array<int, 6542> ret;
bool not_prime[N] = {};
int prime_cnt = 0;
for (int i = 2; i < N; i++) {
if (!not_prime[i]) {
ret[prime_cnt++] = i;
for (int j = 2 * i; j < N; j += i) not_prime[j] = true;
}
}
return ret;
}();
Here I manually specified the ret
's array size. When I want to change N
, I have to re-run this loop to see what the final prime_cnt
value is and manually specify it. Particularly, if I increase N
, I have to first give an upper-bound guess to avoid segfault.
In C++20, we can dynamically allocate memory in compile-time, and thus we have constexpr
vector now. So we no longer need to worry about the upper-bound problem. But such a value cannot be used in run-time, which means, this code is invalid.
constexpr auto primes = [] {
constexpr int N = 1 << 16;
std::vector<int> ret;
bool not_prime[N] = {};
for (int i = 2; i < N; i++) {
if (!not_prime[i]) {
ret.push_back(i);
for (int j = 2 * i; j < N; j += i) not_prime[j] = true;
}
}
return ret; // invalid here
}();
So here comes the problem, how do I store such a vector?
An obvious solution is to split this process into two phases. The first one calculates the array size and the second one does the normal calculation. But this needs extra code and computing resources. Is there an elegant and automatic way to achieve this goal?