是否可以以编程方式初始化constexpr std :: array成员

时间:2018-05-09 23:12:27

标签: c++ constexpr stdarray

让我们假设我想编写一个包含成员constexpr std :: array的struct,其中包含前N个fibs,其中N是模板参数。

这样的东西,但在编译时可以使用val:

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 :(得分:3)

你不需要任何特别的东西,FILE功能要求现在非常放松:

constexpr

(try it live)

  

#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>(); } 构造函数不是constexpr

显然它有no user-defined constructors at all,所以没有什么可以阻止它构建为std::array

答案 1 :(得分:1)

您可以立即使用名为lambda:

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

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

        return a;
    }();
};

但正如HolyBlackCat所说,std::array是constexpr可构造的,因为它没有定义的构造函数,只有编译器定义的构造函数。

这是live example at coloring