使用pybind11传递STL容器时出现问题



我的目标是能够通过std::map<双,双>从Python到C++,用C++填充它,然后在Python端查看结果。这是如何实现的?我甚至连std::向量都无法工作。

我在C++中有一个函数定义,比如这个

void predict(std::vector<T>& seq, std::map<T, double>& probabilities)

main.cpp看起来像这个

#include "node.h"
#include "probtree.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
PYBIND11_MAKE_OPAQUE(std::vector<double>);
PYBIND11_MAKE_OPAQUE(std::map<double, double>);
namespace py = pybind11;
using namespace std;
int main(int argc, char** argv){
}
PYBIND11_MODULE(sps_c, m){
py::bind_vector<std::vector<double>>(m, "VectorD");
py::bind_map<std::map<double, double>>(m, "MapDD");
py::class_<ProbTree<double>>(m, "ProbTree")
.def(py::init())
.def("process", &ProbTree<double>::process)
.def("predict", &ProbTree<double>::predict)
;
}

我所期望的一切都不起作用:

>>> import sps_c
>>> pt = sps_c.ProbTree
>>> vd = sps_c.VectorD
>>> m = sps_c.MapDD
>>> pt.process(vd)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: process(): incompatible function arguments. The following argument types are supported:
1. (self: sps_c.ProbTree, arg0: sps_c.VectorD) -> None
Invoked with: <class 'sps_c.VectorD'>

也许是名单?

>>> pt.process([1.0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: process(): incompatible function arguments. The following argument types are supported:
1. (self: sps_c.ProbTree, arg0: sps_c.VectorD) -> None
Invoked with: [1.0]

我该如何做到这一点?

STL方法不可用也有一个问题:

vd.push_back(1.0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'sps_c.VectorD' has no attribute 'push_back'

我必须写一堆样板才能让STL容器工作吗?

您的第一个示例不起作用,因为您使用类而不是实例调用方法。我认为这应该有效:

>>> pt = sps_c.ProbTree()
>>> vd = sps_c.VectorD()
>>> pt.process(vd)

关于你的第二个例子:没有自动类型转换,所以你需要自己转换:

>>> pt_instance.process(sps_c.VectorD(vd))

关于第三个示例:push_back和其他方法以其公共Python名称提供。这并没有很好的记录,所以这里有一个列表(从这里(:

bind_vector公开了appendclearextendinsertpop和一些迭代器方法。bind_map公开了keysvaluesitems和一些迭代器方法。

如果包含的类型不可复制,则这些方法可能不可用。

最新更新