【问题标题】:PyBind11 Template Class of Many Types多种类型的 PyBind11 模板类
【发布时间】:2018-05-09 07:57:17
【问题描述】:

我想使用 PyBind11 来包装一个专门的数组类。但是,该数组有多种形式(每种普通旧数据类型一种)。代码如下所示:

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)
    //...
    //...

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

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: class c++11 templates macros pybind11


    【解决方案1】:

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

    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);
    }
    

    然后多次调用:

    declare_array<float>(m, "float");
    declare_array<int>(m, "int");
    ...
    

    【讨论】:

    • 如果其他人感到困惑,那些declare_array 调用仍然需要进入PYBIND11_MODULE(my_module_name, m) 调用。
    • 如何扩展它以允许类中的模板化方法?在我的示例中,例如,如果方法“size”是模板化的(比如我想公开函数 size),则编译失败。但是,例如,如果我在 size 的定义中将 'Class' 替换为 'Array2D' ,它将编译。问题是我无法使用您的解决方案来避免重复代码...
    • 任何人都可以看看here。我也从这个答案中得到了帮助。
    猜你喜欢
    • 2019-08-20
    • 2013-07-11
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    相关资源
    最近更新 更多