Sto usando Boost.Python per creare moduli Python dalle classi C++. E ho avuto un problema con i riferimenti.Boost.Python - Come restituire per riferimento?
Condider il seguente caso in cui ho una classe Foo con metodi get sovraccaricati che possono essere restituiti per valore o riferimento.
Specificare che il ritorno in valore deve essere utilizzato è stato facile dopo aver digitato una firma. Ma penso che dovrebbe essere possibile anche restituire un riferimento usando uno return_value_policy
. Tuttavia, utilizzando ciò che sembrava appropriato (doc); return_value_policy<reference_existing_object>
non sembra funzionare.
Ho frainteso cosa fa?
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: so che potrebbe essere pericoloso fare riferimento a un oggetto esistente senza la gestione della vita.
Aggiornamento:
Sembra che funziona per gli oggetti, ma non i tipi di dati di base.
Prendete questo esempio rivisto:
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);
;
}
Che a un test ha dato il risultato atteso:
>>> foo1 = Foo(123)
>>> foo1.get()
123.0
>>> foo2 = foo1.get_self()
>>> foo2.set(1)
>>> foo1.get()
1.0
>>> id(foo1) == id(foo2)
False
Sì, so che tutto è riferimento in Python. Quando creo un metodo python con Boost.Python che restituisce "per valore" restituisce una copia di quel tipo. Quello che voglio fare è * non * copiare, ma creare invece un riferimento alla stessa istanza. – mandrake