c ++使用变量编译时条目数初始化函数指针数组

问题描述

对于嵌入式解决方案,我想定义一个void(*relay)(void)函数数组,该函数用作仅接受无状态void(*f)(void)回调的库的回调中继。然后,中继将调用实际的std::function回调。

下面的代码运行良好。但是,我正在寻找一种更改中继功能的可能性,而不必手动将其初始化类型输入数组的方法。编译时的解决方案很好,但在运行时初始化数组也可以。

有机会在C ++中实现这样的事情吗?

constexpr size_t nrOfRelays = 5;

std::function<void(void)> cb[nrOfRelays]; // callbacks

void (*const relays[nrOfRelays])(void)    // array of pointers to void(*relay)(void)
{
    [] { cb[0](); },[] { cb[1](); },[] { cb[2](); },[] { cb[3](); },[] { cb[4](); },};

void test(unsigned nr,std::function<void(void)> callback)
{
    cb[nr] = callback;
    attachCallback(nr,relays[nr]); // lib requires a void(*f)() callback
}

解决方法

我认为使用纯数组是不可能的。您需要使用std::array之类的东西才能从帮助函数/ lambda返回它。

这是带有Lambda模板的C ++ 20解决方案:

constexpr std::array<void(*)(),nrOfRelays> relays =
    []<std::size_t ...I>(std::index_sequence<I...>) {
        return std::array<void(*)(),nrOfRelays>{[]{cb[I]();}...};
    }(std::make_index_sequence<nrOfRelays>{});

这是一个带有辅助功能的C ++ 17:

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

如果将lambda替换为模板函数,则可以在C ++ 14中使用第二种解决方案:

template <std::size_t I> void helper() {cb[I]();}

template <std::size_t ...I>
constexpr std::array<void(*)(),nrOfRelays>{helper<I>...};
}

constexpr auto relays = MakeRelays(std::make_index_sequence<nrOfRelays>{});

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...