ARTICLE AD BOX
I understand that constexpr can compute results at compile time. Therefore, I'd like to try using compile-time computation to obtain a table of prime numbers.
Below is the code that I've managed to compile after multiple attempts.
#include <vector> #include <algorithm> #include <print> #include <array> //Returns a std::array containing all prime numbers in the range [1, n]. template<int n> consteval auto get_primes(){ auto inner_get_primes = []() constexpr { auto vis = std::vector<bool>(n + 1, false); auto primes = std::vector<int>(); for(int i = 3; i <= n; i += 2) { // Skip all even numbers if(not vis[i]){ primes.push_back(i); } for(int j = 0; j < primes.size() and primes[j] <= n / i; j++){ vis[i * primes[j]] = true; if(i % primes[j] == 0) break; } } return primes; }; auto result = std::array<int, inner_get_primes().size() + 1>{2}; auto primes = inner_get_primes(); std::copy(primes.begin(), primes.end(), result.begin() + 1); return result; } int main(){ constexpr int n = 400; constexpr auto primes = get_primes<n>(); std::println("the count of primes in [1, {}] = {}", n, primes.size()); std::println("primes = {}", primes); }In the code above, I had to call inner_get_primes() twice. When I tried the following code, the compiler gave me an error.
#include <vector> #include <algorithm> #include <print> #include <array> //Returns a std::array containing all prime numbers in the range [1, n]. template<int n> consteval auto get_primes(){ auto inner_get_primes = []() constexpr { auto vis = std::vector<bool>(n + 1, false); auto primes = std::vector<int>(); for(int i = 3; i <= n; i += 2) { // Skip all even numbers if(not vis[i]){ primes.push_back(i); } for(int j = 0; j < primes.size() and primes[j] <= n / i; j++){ vis[i * primes[j]] = true; if(i % primes[j] == 0) break; } } return primes; }; constexpr auto primes = inner_get_primes(); auto result = std::array<int, primes.size() + 1>{2}; std::copy(primes.begin(), primes.end(), result.begin() + 1); return result; } int main(){ constexpr int n = 400; constexpr auto primes = get_primes<n>(); std::println("the count of primes in [1, {}] = {}", n, primes.size()); std::println("primes = {}", primes); }The output of compiler is:
[Error]‘inner_get_primes.get_primes<400>()::<lambda()>()’ is not a constant expression because it refers to a result of ‘operator new’This makes me very confused. Although primers holds the dynamically allocated memory at compile time, that memory is released when result is returned.
Why isn't this allowed?
