vector_indexing_suite seems to break the use of return_internal_reference

Ouverte
#299 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
35/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
À l'abandon
Stack technique
cpp, python

Piste de recherche

Commencez par l’exemple Boost.Python lié sur return_internal_reference et construisez le module C++ présenté, qui expose Foo, Bar et FooList. Exécutez la séquence Python qui ajoute un deuxième Foo, puis cherchez pourquoi la référence Bar renvoyée précédemment change alors que foo_ref.get_bar() reste valide. Le travail est terminé lorsque la référence interne reste valide après l’agrandissement du vecteur.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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
Langage dominant
C++
Étoiles
537
Forks
223
Merge moyen
11 h 22 min
PR mergées (30 j)
2

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de boostorg/python

Toutes les issues de boostorg/python

Issues similaires

Plus d'issues C++

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.