Fab*_*bio 2 c c++ templates c-preprocessor c++11
我正在处理第三方C++库,它广泛使用模板.这使得很难为我的框架使用它创建一个C API.
提取问题,假设库提供了以下功能:
template <int i> void foo();
template <int i> void zoo(int v);
Run Code Online (Sandbox Code Playgroud)
我想用函数头创建一个C API:
extern "C" void c_foo(int i);
extern "C" void c_zoo(int i, int v);
Run Code Online (Sandbox Code Playgroud)
一个明显的实现可能是:
void c_foo(int i)
{
switch(i) {
case 1: foo<1>(); break;
case 2: foo<2>(); break;
case 3: foo<3>(); break;
default: break;
};
};
Run Code Online (Sandbox Code Playgroud)
并做同样的事情void zoo(int).
如果可能值的范围i很小,这可以正常工作.如果我想处理i[1,100]中的所有可能值,那么以这种方式编写代码变得非常难看,因为有很多重复.
有没有更紧凑的方法来做到这一点,即编写更少的代码行?也许使用递归预处理器宏?
您可以在内部使用模板来生成必要的代码.
一种方法是生成一个包含100个函数指针的调度表,然后在运行时对其进行索引.c_foo将生成一个编译时索引序列并调用一个帮助器:
extern "C" void c_foo(int i) {
c_foo_impl(std::make_integer_sequence<int,100>{}, i);
}
Run Code Online (Sandbox Code Playgroud)
这个帮助器将生成调度表并执行调用:
template <int... Is>
void c_foo_impl (std::integer_sequence<int,Is...>, int i) {
constexpr std::array<void(*)(), sizeof...(Is)> dispatch = { &foo<Is>... };
//assert or some other error handling for i > sizeof...(Is)
dispatch[i]();
}
Run Code Online (Sandbox Code Playgroud)
然后你可以做同样的事情zoo:
extern "C" void c_zoo(int i, int v) {
c_zoo_impl(std::make_integer_sequence<int,100>{}, i, v);
}
template <int... Is>
void c_zoo_impl (std::integer_sequence<int,Is...>, int i, int v) {
constexpr std::array<void(*)(int), sizeof...(Is)> dispatch = { &zoo<Is>... };
//assert or some other error handling for i > sizeof...(Is)
dispatch[i](v);
}
Run Code Online (Sandbox Code Playgroud)
如果你发现在一些地方需要这个,你可以抽象出一些细节,或者使用像Petra这样的库,它提供了一个switch_table执行这种映射的库.
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |