boostorg / boostorg/python

vector_indexing_suite seems to break the use of return_internal_reference

Aperta
#299 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
C++
Stelle
537
Fork
223
Merge medio
11h 22m
PR unite (30g)
2

Descrizione

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

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.