Search code examples
c++c++11c++17constexprprecompile

Modern C++: initialize constexpr tables


Suppose I have a class X, which functionality requires a lot of constant table values, say an array A[1024]. I have a recurrent function f that computes its values, smth like

A[x] = f(A[x - 1]);

Suppose that A[0] is a known constant, therefore the rest of the array is constant too. What is the best way to calculate these values beforehand, using features of modern C++, and without storaging file with hardcoded values of this array? My workaround was a const static dummy variable:

const bool X::dummy = X::SetupTables();

bool X::SetupTables() {
    A[0] = 1;
    for (size_t i = 1; i <= A.size(); ++i)
        A[i] = f(A[i - 1]);
}

But I believe, it’s not the most beautiful way to go. Note: I emphasize that array is rather big and I want to avoid monstrosity of the code.


Solution

  • Since C++14, for loops are allowed in constexpr functions. Moreover, since C++17, std::array::operator[] is constexpr too.

    So you can write something like this:

    template<class T, size_t N, class F>
    constexpr auto make_table(F func, T first)
    {
        std::array<T, N> a {first};
        for (size_t i = 1; i < N; ++i)
        {
            a[i] = func(a[i - 1]);
        }
        return a;
    }
    

    Example: https://godbolt.org/g/irrfr2