PyBind11多种类型的模板类

Ric*_*ard 5 macros templates class c++11 pybind11

我想使用PyBind11来包装一个专门的数组类.但是,该阵列有多种形式(每种plain-old-datatype一种).代码如下所示:

py::class_<Array2D<float>>(m, "Array2Dfloat", py::buffer_protocol(), py::dynamic_attr())
    .def(py::init<>())
    .def(py::init<Array2D<float>::xy_t,Array2D<float>::xy_t,float>())
    .def("size",      &Array2D<float>::size)
    .def("width",     &Array2D<float>::width)
    .def("height",    &Array2D<float>::height)
    //...
    //...
Run Code Online (Sandbox Code Playgroud)

我想到告诉PyBind11关于这些类的唯一方法是通过使用一个非常大的宏来复制每个POD的上述内容.

有一个更好的方法吗?

Han*_*rén 12

您可以避免使用宏,而是使用模板化声明函数:

template<typename T>
void declare_array(py::module &m, std::string &typestr) {
    using Class = Array2D<T>;
    std::string pyclass_name = std::string("Array2D") + typestr;
    py::class_<Class>(m, pyclass_name.c_str(), py::buffer_protocol(), py::dynamic_attr())
    .def(py::init<>())
    .def(py::init<Class::xy_t, Class::xy_t, T>())
    .def("size",      &Class::size)
    .def("width",     &Class::width)
    .def("height",    &Class::height);
}
Run Code Online (Sandbox Code Playgroud)

然后多次调用它:

declare_array<float>(m, "float");
declare_array<int>(m, "int");
...
Run Code Online (Sandbox Code Playgroud)

  • 为了防止其他人感到困惑,那些“declare_array”调用仍然需要进入“PYBIND11_MODULE(my_module_name, m)”调用。 (10认同)