Estoy usando Boost.Python para crear módulos de Python a partir de clases de C++. Y encontré un problema con las referencias.Boost.Python - ¿Cómo devolver por referencia?
Considere el siguiente caso en el que tengo una clase Foo con métodos de obtención sobrecargados que pueden devolver por valor o por referencia.
Especificar que el retorno por valor debería ser utilizado fue fácil una vez que escribí una firma. Pero creo que debería ser posible devolver una referencia también usando un return_value_policy
. Sin embargo, usando lo que parecía apropiado (doc); return_value_policy<reference_existing_object>
no pareció funcionar.
¿He entendido mal qué hace?
struct Foo {
Foo(float x) { _x = x; }
float& get() { return _x; }
float get() const { return _x; }
private:
float _x;
};
// Wrapper code
BOOST_PYTHON_MODULE(my_module)
{
using namespace boost::python;
typedef float (Foo::*get_by_value)() const;
typedef float& (Foo::*get_by_ref)();
class_<Foo>("Foo", init<float>())
.def("get", get_by_value(&Foo::get))
.def("get_ref", get_by_ref(&Foo::get),
return_value_policy<reference_existing_object>())//Doesn't work
;
}
Nota: Sé que podría ser peligroso hacer referencia al objeto existente sin la administración de por vida.
Actualización:
Parece que funciona para los objetos, pero no tipos de datos básicos.
Tome este ejemplo revisada:
struct Foo {
Foo(float x) { _x = x; }
float& get() { return _x; }
float get() const { return _x; }
void set(float f){ _x = f;}
Foo& self(){return *this;}
private:
float _x;
};
// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(my_module)
{
typedef float (Foo::*get_by_value)() const;
class_<Foo>("Foo", init<float>())
.def("get", get_by_value(&Foo::get))
.def("get_self", &Foo::self,
return_value_policy<reference_existing_object>())
.def("set", &Foo::set);
;
}
Lo que en una prueba dio el resultado esperado:
>>> foo1 = Foo(123)
>>> foo1.get()
123.0
>>> foo2 = foo1.get_self()
>>> foo2.set(1)
>>> foo1.get()
1.0
>>> id(foo1) == id(foo2)
False
Sí, sé que todo es referencias en Python. Cuando creo un método de Python con Boost.Python que devuelve "por valor", devuelve una copia de ese tipo. Lo que quiero hacer es * no * copiar, sino crear una referencia a la misma instancia. – mandrake