Reputation: 21508
I have an array whose size is set using a compile-time constant (a pre-processor #define
in my case). I need to initialize it using consecutive numbers at compile-time. How can I do this?
Simplified example:
#define ARR_SZ 5
struct C {
C(int a) : a(a) {}
int a;
};
C arr[ARR_SZ] = {{0},{1},{2},{3},{4}}; // This needs to adapt to any number
I can use C++11, but not newer (although I would be interested to learn of newer techniques even if I can't use them for this project)
Upvotes: 2
Views: 336
Reputation: 170163
Since boost was mentioned in the comment section, here's another totally different solution based on Boost.PP. It's also entirely C++03.
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#define ARR_SZ 5
struct C {
C(int a) : a(a) {}
int a;
};
#define INIT(z, n, d) BOOST_PP_COMMA_IF(n) C(n)
C arr[ARR_SZ] = { BOOST_PP_REPEAT(ARR_SZ, INIT, ?) };
int main () {
}
BOOST_PP_REPEAT
will expand to INIT(z, 0, ?) ... INIT(z, 4, ?)
. The z
is not relevant to our goal, and the ?
token is just a placeholder. Since INIT
in turn expands to C(n)
for n
from 0 to 4 (comma delimited), we get an initializer for a regular C style array.
Upvotes: 1
Reputation: 170163
C++14 code (because of std::integer_sequence
):
#include <type_traits>
#include <array>
#define ARR_SZ 5
struct C {
C(int a) : a(a) {}
int a;
};
template<int ...Is>
auto make_C_arr(std::integer_sequence<int, Is...>) -> std::array<C, sizeof...(Is)> {
return {{ {Is}... }};
}
auto arr = make_C_arr(std::make_integer_sequence<int, ARR_SZ>{});
int main () {
}
std::integer_sequence
and the like are implementable in C++11 however as noted in a comment, so substituting the standard version for a home-brewed one will give a C++11 specific solution.
Upvotes: 4