给定function_sig
的函数指针数组,我想将它初始化为一组模板函数指针,这些指针是通过模板参数索引的。这可能吗?
E.g。
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),我就是我喜欢不这样做。
答案 0 :(得分:1)
问题是获得从0到ARRAY_SIZE - 1
的可变范围。
我建议在基类array
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。:我已将ARRAY_SIZE
的类型从int
更改为size_t
;希望不是问题
p.s.2:抱歉我的英语不好。
---编辑:添加了C ++ 14示例---
如果你(当你)可以使用C ++ 14,你可以使用std::index_sequence
和std::make_index_sequence
,丢掉range
和rangeH
。
示例变为
#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;
}
答案 1 :(得分: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
等人。