vector_indexing_suite seems to break the use of return_internal_reference

未关闭
#299 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
cpp, python

调研方向

从链接的 Boost.Python return_internal_reference 示例开始,构建所示的暴露 Foo、Bar 和 FooList 的 C++ 模块。运行追加第二个 Foo 的 Python 序列,然后调查为什么之前返回的 Bar 引用会发生变化,而 foo_ref.get_bar() 仍然有效。完成标准是 vector 增长后内部引用仍然有效。

由索引模型根据 Issue 内容生成。

描述

I can create a class Foo that returns an internal reference to a class Bar and everything seems to work just fine. However, when I try and expose a vector of Foo using the vector_indexing_suite, I get some weird behavior. In Python, a reference to the underlying Bar of a Foo in a vector of Foos gets corrupted when a new Foo is appended to the vector.

Since most of the code comes straight out of the Boost Python docs, I assume it should work.

The issue can be replicated by making a few modifications to an example from the Boost Python docs.

#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>


#include <vector>

class Bar
{
 public:
   Bar(int x) : x(x) {}
   int get_x() const { return x; }
   void set_x(int x) { this->x = x; }

   bool operator==(const Bar &other) const { return other.x == x;}
   bool operator!=(const Bar &other) const { return !(other == (*this)); }

 private:
   int x;
};

class Foo
{
 public:
   Foo(int x) : b(x) {}

   // Returns an internal reference
   Bar const& get_bar() const { return b; }

   bool operator==(const Foo &other) const {return other.b == b;}
   bool operator!=(const Foo &other) const { return !(other == (*this)); }

 private:
   Bar b;
};

using namespace boost::python;
BOOST_PYTHON_MODULE(boosttest)
{
   class_<Bar>("Bar", init<int>())
      .def("get_x", &Bar::get_x)
      .def("set_x", &Bar::set_x)
      ;

   class_<Foo>("Foo", init<int>())
      .def("get_bar", &Foo::get_bar
          , return_internal_reference<>())
      ;

   class_<std::vector<Foo>>("FooList")
      .def(vector_indexing_suite<std::vector<Foo>>())
      ;
}

Then on the Python side, we get the following.

>>> import boosttest
>>> foolist = boosttest.FooList()
>>> foolist.append(boosttest.Foo(2))
>>> foo_ref = foolist[0]
>>> bar_ref = foo_ref.get_bar()
>>> bar_ref.get_x()
2
>>> foolist.append(boosttest.Foo(3))
>>> bar_ref.get_x()
-572662307
>>> foo_ref.get_bar().get_x()
2
主要语言
C++
星标
537
派生
223
平均合并
11 小时 22 分钟
30 天内合并 PR
2

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

boostorg/python 的其他 Issue

查看 boostorg/python 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。