user2426460
user2426460

Reputation: 33

Compute std::vector in consteval context and copy values to std::array in C++20 or later

I am trying to utilize std::vector, which has constexpr member functions since C++20, for compile-time calculations with a statically knowable but non-obvious number of values and then carry those values over to runtime by writing them into an array.

I understand that I cannot directly carry the vector over into the runtime context because everything that was allocated at compile-time must be deallocated at compile-time. I also understand that I need a function template at at least one point because function's return types cannot depend on the argument.

This is my attempt.

#include <array>
#include <vector>
#include <iostream>

consteval std::vector<int> primes_helper(int n) {
    std::vector<int> v;
    for (int i = 2; i < n; ++i) {
        bool prime = true;
        for (int j = 2; j * j <= i; ++j) {
            prime = prime && (i % j != 0);
            if(!prime) break;
        }
        if(prime) v.push_back(i);
    }
    return v;
}

template <int N>
consteval auto primes() {
    constexpr auto primes = primes_helper(N);
    std::array<int, primes.size()> out;
    for(int i = 0; i < primes.size(); ++i)
        out[i] = primes[i];
    return out;
}

int main() {
    constexpr auto p = primes<1000>();
    std::cout << p.size() << "\n";
    return 0;
}

Computing prime numbers is a toy example, what I'm trying to understand is, why the compiler complains that primes in primes() is supposedly not initialized by a constant expression and what modifications would be necessary to make it work.

A modified version that essentially duplicates the logic but still calls the helper function to obtain the array size (https://godbolt.org/z/nzYGKK83P) works.

Upvotes: 0

Views: 27

Answers (0)

Related Questions