用于生成 pybind11 绑定的模板元函数
Template metafunctions to generate pybind11 bindings
我正在尝试使用 pybind11 为某些 C++ 函数创建 python 绑定。这些函数是模板化的,但在 python 绑定中,我需要模板参数之一作为函数参数。目前我的方法是对每个模板参数进行大量重复。
enum MyEnum {E1, E2, E3};
template<typename T, MyEnum E>
returnType templFunction(int arg){
<function body>
}
PYBIND11_MODULE(moduleName, m){
m.def("pyFunction1", [](int arg, MyEnum e){
switch(e){
case MyEnum::E1: return templFunction<templParam1, E1>(arg);
case MyEnum::E2: return templFunction<templParam1, E2>(arg);
case MyEnum::E3: return templFunction<templParam1, E3>(arg);
default: throw std::invalid_argument("Unknown enum type ...");
}
});
m.def("pyFunction2", [](int arg, MyEnum e){
switch(e){
case MyEnum::E1: return templFunction<templParam2, E1>(arg);
case MyEnum::E2: return templFunction<templParam2, E2>(arg);
case MyEnum::E3: return templFunction<templParam2, E3>(arg);
default: throw std::invalid_argument("Unknown enum type ...");
}
});
// for template type temlParam3, only E1 and E2 are valid enums
m.def("pyFunction3", [](int arg, MyEnum e){
switch(e){
case MyEnum::E1: return templFunction<templParam3, E1>(arg);
case MyEnum::E2: return templFunction<templParam3, E2>(arg);
default: throw std::invalid_argument("Unknown enum type ...");
}
});
// more specializations like above
};
有没有什么好的方法可以制作高阶函数,这样我就不需要那么多重复的代码了?
我还有其他具有类似签名和模板参数的函数。所以理想情况下,我想将一个函数句柄(或函数名称)和一个模板参数传递给 "meta-function",它可以根据枚举和给定的模板参数生成特化。
注意:我在每个模板类型(templParam1
、templateParam2
、...)上都有一个静态属性,用于确定该模板参数允许的枚举类型。例如templParam1::allowedEnumTypes = std::vector<myEnum> { E1, E2, E3 };
你可以写
template<typename T, MyEnum... Cases>
return_type switcher(int arg, MyEnum e)
{
return_type r;
bool tests[] = {(e == Cases ? (r = templFunction<T, Cases>(arg), true) : false)...};
for(auto t : tests)
if(t)
return r;
throw std::invalid_argument("Unknown enum type ...");
}
并用作
m.def("pyFunction1", switcher<templParam1, E1, E2, E3>);
m.def("pyFunction2", switcher<templParam2, E1, E2, E3>);
m.def("pyFunction3", switcher<templParam3, E1, E2>);
我正在尝试使用 pybind11 为某些 C++ 函数创建 python 绑定。这些函数是模板化的,但在 python 绑定中,我需要模板参数之一作为函数参数。目前我的方法是对每个模板参数进行大量重复。
enum MyEnum {E1, E2, E3};
template<typename T, MyEnum E>
returnType templFunction(int arg){
<function body>
}
PYBIND11_MODULE(moduleName, m){
m.def("pyFunction1", [](int arg, MyEnum e){
switch(e){
case MyEnum::E1: return templFunction<templParam1, E1>(arg);
case MyEnum::E2: return templFunction<templParam1, E2>(arg);
case MyEnum::E3: return templFunction<templParam1, E3>(arg);
default: throw std::invalid_argument("Unknown enum type ...");
}
});
m.def("pyFunction2", [](int arg, MyEnum e){
switch(e){
case MyEnum::E1: return templFunction<templParam2, E1>(arg);
case MyEnum::E2: return templFunction<templParam2, E2>(arg);
case MyEnum::E3: return templFunction<templParam2, E3>(arg);
default: throw std::invalid_argument("Unknown enum type ...");
}
});
// for template type temlParam3, only E1 and E2 are valid enums
m.def("pyFunction3", [](int arg, MyEnum e){
switch(e){
case MyEnum::E1: return templFunction<templParam3, E1>(arg);
case MyEnum::E2: return templFunction<templParam3, E2>(arg);
default: throw std::invalid_argument("Unknown enum type ...");
}
});
// more specializations like above
};
有没有什么好的方法可以制作高阶函数,这样我就不需要那么多重复的代码了?
我还有其他具有类似签名和模板参数的函数。所以理想情况下,我想将一个函数句柄(或函数名称)和一个模板参数传递给 "meta-function",它可以根据枚举和给定的模板参数生成特化。
注意:我在每个模板类型(templParam1
、templateParam2
、...)上都有一个静态属性,用于确定该模板参数允许的枚举类型。例如templParam1::allowedEnumTypes = std::vector<myEnum> { E1, E2, E3 };
你可以写
template<typename T, MyEnum... Cases>
return_type switcher(int arg, MyEnum e)
{
return_type r;
bool tests[] = {(e == Cases ? (r = templFunction<T, Cases>(arg), true) : false)...};
for(auto t : tests)
if(t)
return r;
throw std::invalid_argument("Unknown enum type ...");
}
并用作
m.def("pyFunction1", switcher<templParam1, E1, E2, E3>);
m.def("pyFunction2", switcher<templParam2, E1, E2, E3>);
m.def("pyFunction3", switcher<templParam3, E1, E2>);