Reputation: 2633
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
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
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