Thijser
Thijser

Reputation: 2633

c++ populate array with predefined values in a clever way

I'm looking for a way to populate an array with elements of values at compile time rather then run time. So what I'm looking for is something like this

#define numbar
Bar foo[] = {Bar(0),Bar(1)....Bar(numbar)}

Does c++ have any way to do this? Perhaps using macro's or something like that?

Upvotes: 0

Views: 316

Answers (2)

Germán Diago
Germán Diago

Reputation: 7673

Assuming c++14:

constexpr auto num_bars = 100;

class Bar {
    constexpr Bar(int i);
};

template <std::size_t ...I>
constexpr auto generate_bars_impl(std::index_sequence<I...>) {
    return {Bar(I)...};
}

template <std::size_t N, typename Indices = std::make_index_sequence<N>>
constexpr auto generate_bars() {
   return generate_bars_impl(Indices());
}

constexpr auto generated = generate_bars<num_bars>();

This will give you an std::initializer_list in C++14. C++11: You should implement index_sequence and I think that initializer_list has no constexpr constructor.

Upvotes: 5

CK1
CK1

Reputation: 714

I am not sure if this is clever enough, but in the case you could use boost preprocessor to create the code as described in you example:

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/seq/enum.hpp>

#define INIT(z, n, initializer)(initializer(n))
#define INIT_ARRAY(N, INITIALIZER) {BOOST_PP_SEQ_ENUM(BOOST_PP_REPEAT(5, INIT, Bar))}

struct Bar
{
    constexpr Bar(int ii) : i(ii) {}
    int i;
};

Bar data[] = INIT_ARRAY(5, Bar);

In general you can solve a lot of repetitive problems this way, but you often makes the code more complex and it less obvious what happens. So you should do this only if you have a lot of such think. Of course you can also do some metaprogramming, which can lead to quite long compile times

Upvotes: 3

Related Questions