问题描述
我想编写一组便利函数,以帮助我使用pybind11绑定类模板实现。我希望这些功能尽可能通用/可重用。
具体地说,我想到的是班级模板
我的目标是编写模板化函数
template <class... Ts>
bind_MyClass(){...}
为给定的模板参数绑定类模板MyClass
,并为Ts...
中的每种类型自动绑定其模板化的成员函数。
作为一个最小的示例,请考虑以下std::tuple
的包装器:
template <class... Ts>
class Tuple
{
public:
template <typename T>
T& get()
{
return std::get<T>(_tuple);
}
template <typename T>
void set(T const& val)
{
this->get<T>() = val;
}
private:
std::tuple<Ts...> _tuple{};
};
借助some help from stackoverflow,我弄清楚了如何使用以下代码绑定Tuple::get
的所有实现:
namespace py = pybind11;
/********************************
* customized pretty type names *
********************************/
template <typename T>
std::string pretty_name()
{
std::ostringstream o;
o << typeid(T).name();
return o.str();
}
template <> std::string pretty_name<int> (){ return "int"; }
template <> std::string pretty_name<std::string>(){ return "str"; }
template <> std::string pretty_name<double> (){ return "double"; }
template <> std::string pretty_name<Tuple<int>> (){ return "TupleInt"; }
template <> std::string pretty_name<Tuple<double,std::string>> (){ return "TupleDoubleStr"; }
/**********************************************************************
* Bind the "get" template of Tuple for all types in a parameter pack *
**********************************************************************/
template <class C>
void bind_member_template_for_all_T(py::class_<C>&,std::string const&){}
template <class C,class T,class... Ts>
void bind_member_template_for_all_T(py::class_<C>& c,std::string const& basename)
{
// bind for T
c.def((basename + pretty_name<T>()).c_str(),&C::template get<T>);
// recursively bind for each T in Ts...
bind_member_template_for_all_T<C,Ts...>(c,basename);
}
/**************************************************
* Bind the Tuple class for a given pack of types *
**************************************************/
template <class... Ts>
void bindTuple(py::module& m,std::string const& name)
{
using Class = Tuple<Ts...>;
py::class_<Class> c(m,name.c_str());
c.def(py::init<>());
bind_member_template_for_all_T<Class,"get_");
}
/*********************************************************
* Actually bind some realizations of the Tuple template *
*********************************************************/
PYBIND11_MODULE(cmake_example,m)
{
bindTuple<int>(m,"TupleInt");
bindTuple<double,std::string>(m,"TupleDoubleString");
bindTuple<Tuple<int>,Tuple<double,std::string>>(m,"WeirdnestedTuple");
}
是否可以以某种方式概括bind_member_template_for_all_T
,以便我可以向其抛出其他成员模板,例如Tuple::set
?还是我必须为要绑定的每个成员编写两个bind_member_template_for_all_T
重载?后者会使我的代码杂乱无章。
您可以在此Github repo中找到此示例的源代码。
编辑:
当然,一种选择是为每个类而不是每个类成员编写一个bind_member_template_for_all_T
函数:
template <class C>
void bind_member_template_for_all_T(py::class_<C>&){}
template <class C,class... Ts>
void bind_member_template_for_all_T(py::class_<C>& c)
{
c.def(("get_" + pretty_name<T>()).c_str(),&C::template get<T>)
.def(("set_" + pretty_name<T>()).c_str(),&C::template set<T>);
bind_member_template_for_all_T<C,Ts...>(c);
}
template <class... Ts>
void bindTuple(py::module& m,name.c_str());
c.def(py::init<>());
//bind set,set const and get
bind_member_template_for_all_T<Class,Ts...>(c);
}
但是,如果可以将依赖于可变参数模板的任何类的功能归纳为一个函数,那仍然很好。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)