Programmatically create static arrays at compile time in C++
The closest you can get is using C++0x features to initialize local or member arrays of templates from a variadic template argument list.
This is of course limited by the maximum template instantiation depth and wether that actually makes a notable difference in your case would have to be measured.
Example:
template<unsigned... args> struct ArrayHolder {
static const unsigned data[sizeof...(args)];
};
template<unsigned... args>
const unsigned ArrayHolder<args...>::data[sizeof...(args)] = { args... };
template<size_t N, template<size_t> class F, unsigned... args>
struct generate_array_impl {
typedef typename generate_array_impl<N-1, F, F<N>::value, args...>::result result;
};
template<template<size_t> class F, unsigned... args>
struct generate_array_impl<0, F, args...> {
typedef ArrayHolder<F<0>::value, args...> result;
};
template<size_t N, template<size_t> class F>
struct generate_array {
typedef typename generate_array_impl<N-1, F>::result result;
};
Usage for your 1..5
case:
template<size_t index> struct MetaFunc {
enum { value = index + 1 };
};
void test() {
const size_t count = 5;
typedef generate_array<count, MetaFunc>::result A;
for (size_t i=0; i<count; ++i)
std::cout << A::data[i] << "\n";
}
Since C++17 you can use a constexpr
lambda an invoke it in place. The only "downside" is that you will have to use std::array
instead of c-style array:
constexpr auto myArray{[]() constexpr{
std::array<MyType, MySize> result{};
for (int i = 0; i < MySize; ++i)
{
result[i] = ...
}
return result;
}()};
As an example that's how you could create an array with powers of two:
constexpr auto myArray{[]() constexpr{
constexpr size_t size = 64;
std::array<long long, size> result{};
result[0] = 1;
for (int i = 1; i < size; ++i)
{
result[i] = result[i - 1] * 2;
}
return result;
}()};
As you can see, you can even reference the previous cells of the array.
This technique is called IILE or Immediately Invoked Lambda Expression.