How to wrap templated classes with pybind11

Refresh

December 2018

Views

503 time

5

I've got a class structure similar to the one below, where I have two types A and B with similar signatures that only differ in argument/return type. I then use a class template to be able to process both classes, achieving a static variant of ducktyping in Python. Now I want to wrap this code into Python with pybind11, where I hope to get a class that takes both types using standard, dynamic ducktyping. How do I do this?

I'm basically looking for a way to disable the strict type check in pybind11 or specify multiple types such that both TypeA and TypeB are accepted. The way the example below is defined, only TypeA passes the check. I also can't unify A and B into a base class because of the 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();
}

0 answers