设计建议:“unique_ptr”和 pybind11

Design advice: `unique_ptr` and pybind11

提问人:Bubaya 提问时间:11/2/2023 最后编辑:Bubaya 更新时间:11/2/2023 访问量:41

问:

我有一个设置,其中资源可以通过各种过滤器传递,这些过滤器也派生自 .共享 的所有权是没有意义的,因为资源在检索时会被消耗掉。我决定使用一些,如下所示:RFRRunique_ptr

struct R{
  virtual int yield() = 0;
};
struct F{
  F(std::unique_ptr<R> r): _r(std::move(r)) {}
  int yield(){return _r->yield() + 1;}
  std::unique_ptr<R> _r;
};

当然,除了课程更有趣。现在我正在尝试将其与 pybind11 绑定。Pybind 似乎不喜欢 ,如文档中所述。我怎样才能规避这个问题?我看到了可能性:unique_ptr

  1. 替换为 pybind11 理解的内容。这意味着在 C++ 和 Python 端,尽管已经被其他一些 .std::unique_ptrRFRF
    1. 而不是采取 ,采取 .然后,可以通过将参数设置为零来反映所有权的转移。不过,似乎不是很C++。std::unqique_ptrR*&
  2. 编写一个不需要的包装器。这将有同样的问题,但仅限于 Python 端。我可能会实现一些来解决这个问题。另外,我不需要更改现有代码的接口。缺点是,我需要复制我需要的所有方法。Funique_ptr

这两种解决方案似乎都不太吸引人。有什么替代方案?

C++ 智能指针 pybind11

评论

0赞 Caleth 11/2/2023
需要拥有吗?FR
0赞 Bubaya 11/2/2023
@Caleth 是的,那将是理想的。
0赞 Caleth 11/2/2023
我看到的限制是“虽然允许以这种方式返回唯一指针,但将它们用作函数参数是非法的。...上面的签名意味着 Python 需要放弃传递给此函数的对象的所有权,这通常是不可能的(例如,该对象可能在其他地方被引用)。
0赞 Caleth 11/2/2023
如果你想允许 python 端提供 ,那么你就不能拥有唯一的所有权。R

答:

1赞 Caleth 11/2/2023 #1

语言互操作的一个问题是,您必须遵循两种语言的数据模型。Python 没有资源唯一所有权的概念,这就是为什么 pybind 不允许你向 Python 公开参数的原因。std::unique_ptr

我认为最简单的方法是使用 ,但请注意,这仅用于与 Python 绑定的互操作。您仍然可以在 C++ 端使用,因为有一个转换构造函数。std::shared_ptrF::F(std::unique_ptr<R> r)std::shared_ptr<R>::shared_ptr(std::unique_ptr<R>)