I'd like to use PyBind11 to wrap a specialized array class. However, the array is available in many flavours (one per each plain-old-datatype). The code looks like this:
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)
//...
//...
The only way I've thought of to tell PyBind11 about these classes is by duplicating the above for each POD through the use of a very large macro.
Is there a better way to do this?
A template is a C++ programming feature that permits function and class operations with generic types, which allows functionality with different data types without rewriting entire code blocks for each type.
An individual class defines how a group of objects can be constructed, while a class template defines how a group of classes can be generated. Note the distinction between the terms class template and template class: Class template.
A template is not a class or a function.
Class Template: We can define a template for a class. For example, a class template can be created for the array class that can accept the array of various types such as int array, float array or double array.
You can avoid using macros and instead go with a templated declaration function:
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);
}
And then call it multiple times:
declare_array<float>(m, "float");
declare_array<int>(m, "int");
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With