如何初始化n个函数指针的数组以从0.N-1索引的功能模板



给定一个 function_sig的功能指针数组,我想将其初始化为一组模板函数指针,这些指针是通过模板参数索引的。这可能吗?

,例如

template<int I>
void fn() { /* do something */ }
typedef void(*function_sig)();
template<int ARRAY_SIZE>
struct items
{
  static function_sig array[ARRAY_SIZE];
};
template<int ARRAY_SIZE>
function_sig items<ARRAY_SIZE>::array = { /* what do I put here? */ };

那么,我可以将某些内容放入初始分散列表中,以便将items<ARRAY_SIZE>::array初始化为{ fn<0>, fn<1>, ..., fn<ARRAY_SIZE-1> }

注意:我知道一种使用预处理器魔术来做到这一点的方法,但是我想尝试一下。目前,我认为我必须取消数组,并用像数组一样的作用,但这会导致索引伪阵列时搜索o(n),我'd喜欢不这样做。

问题是获得从0到ARRAY_SIZE - 1的变异范围。

我提出了一个解决方案,该解决方案在基类itemsH

中转移array
#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。:我已经将ARRAY_SIZE的类型从int更改为size_t;希望不是问题

P.S.2:对不起,我的英语不好。

----编辑:添加C 14示例---

如果您(何时)可以使用C 14,则可以使用std::index_sequencestd::make_index_sequence,扔掉rangerangeH

示例变为

#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;
 }
#include <array>
template<int... Is>
struct int_seq { };
namespace detail {
template<int I, int... Is>
struct make_int_seq : make_int_seq<I - 1, I, Is...> { };
template<int... Is>
struct make_int_seq<0, Is...> {
    using type = int_seq<0, Is...>;
};
} // namespace detail
template<int SizeN>
using make_int_seq = typename detail::make_int_seq<SizeN - 1>::type;
template<int I>
void fn() { /* do something */ }
//typedef void(*function_sig)();
using function_sig = void(*)();
template<int ARRAY_SIZE>
struct items {
    static std::array<function_sig, ARRAY_SIZE> array;
};
template<int... Is>
std::array<function_sig, sizeof...(Is)> create_items_array(int_seq<Is...>) {
    return {{ &fn<Is>... }};
}
template<int ARRAY_SIZE>
std::array<function_sig, ARRAY_SIZE> items<ARRAY_SIZE>::array
  = create_items_array(make_int_seq<ARRAY_SIZE>{});

在线演示

使用C 14,int_seq等人消失了,有利于std::integer_sequence等。

最新更新