boostorg / boostorg/python

vector_indexing_suite seems to break the use of return_internal_reference

Aberta
#299 3 comentários 0 reações 0 responsáveis Ver no GitHub
Linguagem predominante
C++
Estrelas
537
Forks
223
Merge médio
11h 22min
PRs com merge (30d)
2

Descrição

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

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.