2

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

1

2 Answers 2

4

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>()); } 
Sign up to request clarification or add additional context in comments.

3 Comments

Wow. The power of fold expressions!
Syntax for fold expression is a bit different. In above, it is normal unpacking parameters pack with multiplying by 3 each value of pack.
Oh, I thought "fold" referred to that too. In this case, the power of the ...!
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 = []{ td::array<int,100> ret{}; for (std::size_t i = 0; i < ret.size(); i++) ret[i] = 3 * (1+i); return ret; }(); 

1 Comment

The plain loop version is nice, but I had to drop the second "constexpr", and make the second line simply as follows: std::array<int,100> ret{}; (in order to compile)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.