c ++使用可变(编译时)条目数初始化函数指针数组
c++ initialize array of function pointers with variable (compiletime) number of entries
对于嵌入式解决方案,我想定义一个 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
之类的东西才能从助手 function/lambda.
return 它
这是一个带有 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> MakeRelays(std::index_sequence<I...>)
{
return std::array<void(*)(), nrOfRelays>{helper<I>...};
}
constexpr auto relays = MakeRelays(std::make_index_sequence<nrOfRelays>{});
对于嵌入式解决方案,我想定义一个 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
之类的东西才能从助手 function/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> MakeRelays(std::index_sequence<I...>)
{
return std::array<void(*)(), nrOfRelays>{helper<I>...};
}
constexpr auto relays = MakeRelays(std::make_index_sequence<nrOfRelays>{});