能否在C++11中实现类似C++17的编译时回调中继函数指针数组?
为C++11实现无状态回调中继数组
需求与原有C++17实现
我们需要一个void(*relay)(void)类型的数组,作为仅接受无状态void(*f)(void)回调的第三方库的回调中继,这些中继会调用实际存储的std::function<void()>回调。以下是适用于C++17的实现方案:
// nrOfRelays 是编译期常量 std::function<void(void)> cb[nrOfRelays]; template <std::size_t ...I> constexpr std::array<void(*)(), nrOfRelays> MakeRelays(std::index_sequence<I...>) { return std::array<void(*)(), nrOfRelays>{[]{cb[I]();}...}; } constexpr auto relays = MakeRelays(std::make_index_sequence<nrOfRelays>{});
问题
由于C++11不支持std::index_sequence,能否实现类似的功能?
C++11兼容实现方案
可以通过递归模板手动模拟索引序列生成来实现相同功能,具体代码如下:
首先,实现编译期索引序列生成模板:
// 递归终止模板 template<std::size_t...> struct IndexSequence {}; // 递归生成索引序列的模板 template<std::size_t N, std::size_t... I> struct MakeIndexSequence : MakeIndexSequence<N-1, N-1, I...> {}; // 递归终止特化 template<std::size_t... I> struct MakeIndexSequence<0, I...> : IndexSequence<I...> {};
然后复用核心逻辑,替换为自定义的索引序列类型:
// nrOfRelays 是编译期常量 std::function<void(void)> cb[nrOfRelays]; template <std::size_t ...I> constexpr std::array<void(*)(), nrOfRelays> MakeRelays(IndexSequence<I...>) { return std::array<void(*)(), nrOfRelays>{[]{cb[I]();}...}; } // 生成中继数组 constexpr auto relays = MakeRelays(MakeIndexSequence<nrOfRelays>{});
补充说明
- 手动实现的
MakeIndexSequence通过递归模板在编译期生成从0到nrOfRelays-1的索引序列,功能等价于C++17的std::make_index_sequence。 - 核心的
MakeRelays函数逻辑和C++17版本一致,利用参数包展开生成每个中继函数,每个中继都会调用对应索引的std::function。 - 若旧编译器对C++11的
constexpr支持有限,可去掉constexpr,改为全局静态数组:static auto relays = MakeRelays(MakeIndexSequence<nrOfRelays>{});
内容的提问来源于stack exchange,提问作者luni64
相关产品推荐
相关产品推荐

