Joh*_*han 6 c++ python templates pybind11
我有一个类似于下面的类结构,其中我有两个类型A和B具有相似的签名,只有参数/返回类型不同.然后我使用类模板来处理这两个类,在Python中实现了ducktyping的静态变体.现在我想用pybind11将这段代码包装到Python中,我希望得到一个使用标准的动态ducktyping来获取两种类型的类.我该怎么做呢?
我基本上是在寻找一种方法来禁用pybind11中的严格类型检查或指定多种类型,以便接受TypeA和TypeB.定义下面示例的方式,只有TypeA通过检查.由于功能签名不同,我也无法将A和B统一到基类中.
#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();
}
Run Code Online (Sandbox Code Playgroud)
如果您绑定的函数具有可以在 C++ 中“驱动”推理的参数,您可以使用它们来驱动重载解析pybind11:
https ://pybind11.readthedocs.io/en/stable/advanced/functions.html#重载解析顺序
例如,您可以将实例化绑定为重载,然后弄清楚pybind11:
// Let's say `DuckType::runType` is static.
m.def("runType", &DuckType<TypeA>::runType, py::arg("arg"));
m.def("runType", &DuckType<TypeB>::runType, py::arg("arg"));
Run Code Online (Sandbox Code Playgroud)
然后,调度将在 Python 中工作,假设用户可以实例化这些类型,并且InType定义 s 以便它们不会意外拦截另一个类的类型:
runType(arg=1.2) # TypeA
runType(arg="hello world") # TypeB
Run Code Online (Sandbox Code Playgroud)