Можно ли программно инициализировать constexpr std :: array member? - PullRequest
0 голосов
/ 10 мая 2018

Предположим, я хочу написать структуру, которая имеет член constexpr std :: array, который содержит первые N fibs, где N - аргумент шаблона.

Примерно так, но vals доступен во время компиляции:

template <int N>
struct first_n_fibs {
    static_assert(N>0);
    static const std::array<int, N> vals;
    static std::array<int, N> init_fibs(){
        std::array<int,N> result;
        if (N==1) {
            return std::array<int,N>{1};
        } else {
            result[0]=1;
            result[1]=1;
            for(int i =2; i<N;++i) {
                result[i]=result[i-2]+result[i-1];
            }
        }
        return result;
    }
};

template<int N>
const std::array<int, N> first_n_fibs<N>::vals=init_fibs();


int main(){
    std::cout << first_n_fibs<2>::vals.back() << std::endl;
    std::cout << first_n_fibs<5>::vals.back() << std::endl;
    std::cout << first_n_fibs<6>::vals.back() << std::endl;
}

Я подозреваю, что нет никакого обходного пути, так как конструкторы std :: array не являются constexpr, поэтому, если кто-то знает какие-либо обходные пути, включающие массивы C или boost, я был бы рад этому.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вы можете использовать сразу же называется лямбда:

struct foo {
    static constexpr auto arr = []{
        std::array<int, 6> a{};

        for (auto& e : a) {
            // stuff
        }

        return a;
    }();
};

Но, как сказал HolyBlackCat, std::array является конструктивным constexpr, так как у него нет определенного конструктора, только определенные компилятором.

Вот живой пример при раскраске

0 голосов
/ 10 мая 2018

Вам не нужно ничего особенного, constexpr требования к функциям в наши дни очень смягчены:

#include <iostream>
#include <array>

template <int N> constexpr std::array<int, N> first_n_fibs()
{
    std::array<int, N> ret{};
    ret[0] = 0;
    if (N == 1) return ret;
    ret[1] = 1;
    for (int i = 2; i < N; i++)
        ret[i] = ret[i-2] + ret[i-1];
    return ret;
}

int main()
{
    constexpr auto a = first_n_fibs<3>();
}

(попробуйте вживую)


std::array конструкторы не являются constexpr

По-видимому, вообще не имеет пользовательских конструкторов , поэтому ничто не мешает его конструкции быть constexpr.

...