Reputation: 30058
Lets assume I want to write struct that has a member constexpr std::array that contains first N fibs, where N is a template argument.
Something like this but with vals being avaliable at compile time:
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;
}
I suspect there is no workaround since std::array constructors are not constexpr, so if somebody knows any workarounds involving C arrays or boost I would be happy with that.
Upvotes: 3
Views: 6588
Reputation: 41770
You can use immediately called lambda:
struct foo {
static constexpr auto arr = []{
std::array<int, 6> a{};
for (auto& e : a) {
// stuff
}
return a;
}();
};
But as HolyBlackCat said, std::array
is constexpr constructible, since it has no defined constructor, only compiler defined ones.
Here's live example at coliru
Upvotes: 2
Reputation: 96334
You don't need anything special, constexpr
function requirements are very relaxed these days:
#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
constructors are not constexpr
Apparently it has no user-defined constructors at all, so nothing stops its construction from being constexpr
.
Upvotes: 7