The problem is to get a variadic range from 0 to ARRAY_SIZE - 1
.
I propose a solution that transfer array
in a base class itemsH
#include <iostream>
template <std::size_t ...>
struct range
{ };
template <std::size_t N, std::size_t ... Next>
struct rangeH
{ using type = typename rangeH<N-1U, N-1U, Next ... >::type; };
template <std::size_t ... Next >
struct rangeH<0U, Next ... >
{ using type = range<Next ... >; };
template<int I>
void fn() { std::cout << "[" << I << "]" << std::endl; }
typedef void(*function_sig)();
template <typename T>
struct itemsH;
template <std::size_t ... RNG>
struct itemsH<range<RNG...>>
{
static function_sig array[sizeof...(RNG)];
};
template<std::size_t ARRAY_SIZE>
struct items : public itemsH<typename rangeH<ARRAY_SIZE>::type>
{ };
template <std::size_t ... RNG>
function_sig itemsH<range<RNG...>>::array[sizeof...(RNG)] = { fn<RNG>... };
int main ()
{
items<10> i_10;
for ( unsigned ui = 0U ; ui < 10 ; ++ui )
i_10.array[ui]();
return 0;
}
p.s.: I've changed the type of ARRAY_SIZE
from int
to size_t
; hoping isn't a problem
p.s.2: sorry for my bad English.
--- edit: added C++14 example ---
If you (when you) can use C++14, the you can use std::index_sequence
and std::make_index_sequence
, throwing away range
and rangeH
.
The example become
#include <utility>
#include <iostream>
template<int I>
void fn() { std::cout << "[" << I << "]" << std::endl; }
typedef void(*function_sig)();
template <typename T>
struct itemsH;
template <std::size_t ... RNG>
struct itemsH<std::index_sequence<RNG...>>
{ static function_sig array[sizeof...(RNG)]; };
template<std::size_t ARRAY_SIZE>
struct items : public itemsH<std::make_index_sequence<ARRAY_SIZE>>
{ };
template <std::size_t ... RNG>
function_sig itemsH<std::index_sequence<RNG...>>::array[sizeof...(RNG)]
= { fn<RNG>... };
int main ()
{
items<10> i_10;
for ( unsigned ui = 0U ; ui < 10 ; ++ui )
i_10.array[ui]();
return 0;
}