You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在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>{});

补充说明

  1. 手动实现的MakeIndexSequence通过递归模板在编译期生成从0到nrOfRelays-1的索引序列,功能等价于C++17的std::make_index_sequence。
  2. 核心的MakeRelays函数逻辑和C++17版本一致,利用参数包展开生成每个中继函数,每个中继都会调用对应索引的std::function。
  3. 若旧编译器对C++11的constexpr支持有限,可去掉constexpr,改为全局静态数组:
    static auto relays = MakeRelays(MakeIndexSequence<nrOfRelays>{});
    

内容的提问来源于stack exchange,提问作者luni64

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:01:24