boostorg / boostorg/python

vector_indexing_suite seems to break the use of return_internal_reference

Abierto
#299 3 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
C++
Estrellas
537
Forks
223
Merge medio
11 h 22 min
PR fusionados (30 d)
2

Descripción

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](https://www.boost.org/doc/libs/1_62_0/libs/python/doc/html/reference/function_invocation_and_creation/models_of_callpolicies.html#function_invocation_and_creation.models_of_callpolicies.boost_python_return_internal_ref.example) from the Boost Python docs.

```c++
#include
#include
#include
#include

#include

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", init())
.def("get_x", &Bar::get_x)
.def("set_x", &Bar::set_x)
;

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

class_>("FooList")
.def(vector_indexing_suite>())
;
}
```

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
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.