0

For example, if I wanted a constexpr std::array<int,100> initialised with all the multiples of 3 from 1-300 at compile time how can I do this?

My first thought was to use std::generate, something like:

constexpr std::array<int,100> a { std::generate(a.begin(), a.end(), [n=0]()mutable{ return n+=3; });

I get an error such as <source>:9:52: error: void value not ignored as it ought to be

and I can't use std::generate after this because of course, it's read only at that point

Thanks for any help

tadman
  • 208,517
  • 23
  • 234
  • 262
nectarine
  • 65
  • 4
  • Does this answer your question? [Is it possible to initialize constexpr std::array member in a programtic way](https://stackoverflow.com/questions/50263306/is-it-possible-to-initialize-constexpr-stdarray-member-in-a-programtic-way) – gkhaos Mar 10 '21 at 21:14

2 Answers2

2

You can use index_sequence:

template <size_t ... Indices>
constexpr auto gen(std::index_sequence<Indices...>) {
    return std::array<int,100>{ (Indices * 3)... };
}

int main() {
    constexpr std::array<int,100> a = gen(std::make_index_sequence<100>());
}
rafix07
  • 20,001
  • 3
  • 20
  • 33
0

The trick is to put the code into an immediately-invoked lambda. Then it doesn't matter if you use std::generate or a plain loop:

constexpr std::array<int,100> a = []{
    std::array<int,100> ret{};
    std::generate(ret.begin(), ret.end(),  [n=0]() mutable {return n += 3;});
    return ret;
}();
constexpr std::array<int,100> a = []{
    constexpr std::array<int,100> ret{};
    for (std::size_t i = 0; i < ret.size(); i++)
        ret[i] = 3 * (1+i);
    return ret;
}();
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207