How to wrap template classes with pybind11

I have a class structure similar to the structure below, where I have two types A and B with similar signatures that differ only in argument / return. Then I use the class template to be able to handle both classes, reaching the static ducktyping option in Python. Now I want to wrap this code in Python with pybind11, where I hope to get a class that uses both types using standard dynamic ducktyping. How to do it?

I'm basically looking for a way to turn off strict type checking in pybind11 or to specify multiple types so that both TypeA and TypeB are accepted. The way the example below is defined only checks TypeA. I also cannot combine A and B into a base class due to different function signatures.

#include <pybind11/pybind11.h> #include <iostream> class TypeA { public: typedef double InType; typedef std::string OutType; const OutType operator()(const InType arg) { return std::to_string(arg); } }; class TypeB { public: typedef std::string InType; typedef double OutType; const OutType operator()(const InType arg) { return std::stod(arg); } }; template<typename T> class DuckType { public: void runType(const typename T::InType arg) { T x; const typename T::OutType y = x(arg); std::cout << y << std::endl; } }; namespace py = pybind11; PYBIND11_PLUGIN(ducktyping) { pybind11::module m("ducktyping", "Testing ducktyping with templates"); typedef DuckType<TypeA> Type; py::class_<Type>(m, "DuckType") .def("run_type", &Type::runType); ; return m.ptr(); } 
+6
source share
1 answer

If the function you are binding has arguments that can β€œcontrol” the output in C ++, you could potentially use them to determine the overload resolution in pybind11 : https://pybind11.readthedocs.io/en/stable/advanced/functions .html # overload resolution order

For example, you can bind your instances as overloads, letting pybind11 figure this out:

 // Let say 'DuckType::runType' is static. m.def("runType", &DuckType<TypeA>::runType, py::arg("arg")); m.def("runType", &DuckType<TypeB>::runType, py::arg("arg")); 

Then dispatching will work in Python, assuming that users can create instances of these types, and InType is defined so that they will not accidentally intercept another type of class:

 runType(arg=1.2) # TypeA runType(arg="hello world") # TypeB 
0
source

Source: https://habr.com/ru/post/1269521/


All Articles