PyBind11:返回对std :: unique_ptr的std :: vector的const引用

时间:2020-05-19 16:39:12

标签: c++ c++11 pybind11

我正在尝试将对唯一ptrs向量的const引用从C ++库返回到python接口。我正在尝试类似于以下代码,但是在尝试调用py::bind_vector<std::vector<std::unique_ptr<A>>>

时遇到编译错误
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>

class A
{
  public:
    A( int x ){ i = x; }
    A(const A&) = delete;
    A& operator=(const A&) = delete;
    int getI() { return i; }

  private:
    int i;
};

class Test
{
  public:
    Test(){
      for(int i = 0; i < 10; ++i) {
        avec_.emplace_back( std::make_unique<A>(i));
      }
    }
    Test( const Test& ) = delete;
    Test& operator=(const Test& ) = delete;

    const std::vector<std::unique_ptr<A>>& getVec() const { return avec_; }

  private:
    std::vector<std::unique_ptr<A>> avec_;
};

PYBIND11_MODULE(UniqContainer, m) {

  py::bind_vector<std::vector<std::unique_ptr<A>>>(m, "VecA", py::module_local() );

  py::class_<A>(m, "A")
    .def( py::init<int>() )
    .def( "getI", &A::getI );

  py::class_<Test>(m, "Test" )
    .def( py::init<>() )
    .def( "getVec", &Test::getVec, py::return_value_policy::reference_internal );
}

我的问题是-是否可以在python绑定中返回对std::vector<std::unique_ptr<A>>的const引用?

编辑: 新增:

  • 复制ctor和赋值运算符删除
  • py::return_value_policy::reference_internal

1 个答案:

答案 0 :(得分:0)

这是我能想到的最好的方法。如果将句柄保存到python中的A实例,然后在c ++中删除它们,则可能存在寿命问题。您不能在我正在使用的上下文中使用reference_internal,因为它不知道所指的寿命。您也可以将py::keep_alive显式添加到函数def中,以保持范围。我不知道您的终生要求是什么,并且我对API的那部分仍然有些困惑。

  py::class_<Test>(m, "Test" )
    .def( py::init<>() )
    .def( "getVec",
          [](const Test& obj) {
            auto pylist = py::list();
            for (auto& ptr : obj.getVec()) {
              auto pyobj = py::cast(*ptr, py::return_value_policy::reference);
              pylist.append(pyobj);
            }
            return pylist;
          });
}

基本上,必须手动创建py::list,然后通过引用将其中的智能指针投射到py::object,以填充列表。

(注意,我还删除了py::bind_vector以使所有内容都能编译)