Я использую Boost.Python для создания модулей Python из классов C++. И я столкнулся с проблемой со ссылками.Boost.Python - Как вернуться по ссылке?
Включите следующий случай, когда у меня есть класс Foo с перегруженными методами get, которые могут либо возвращаться по значению, либо по ссылке.
Задание того, что нужно использовать возвращаемое значение, было легко, как только я набрал подпись. Но я думаю, что также возможно вернуть ссылку, используя return_value_policy
. Однако, используя то, что казалось подходящим (doc); return_value_policy<reference_existing_object>
, похоже, не работает.
Я не понял, что он делает?
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
;
}
Примечание: Я знаю, что может быть опасно ссылаться на существующий объект без управления жизненным циклом.
Update:
Похоже, что он работает для объектов, но не основные типы данных.
Возьмите этот пересмотренный пример:
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);
;
}
Который в тесте дали ожидаемый результат:
>>> foo1 = Foo(123)
>>> foo1.get()
123.0
>>> foo2 = foo1.get_self()
>>> foo2.set(1)
>>> foo1.get()
1.0
>>> id(foo1) == id(foo2)
False
Да, я знаю, что все ссылки в Python. Когда я создаю метод python с Boost.Python, который возвращает «по значению», он возвращает копию этого типа. То, что я хочу сделать, это * не * копировать, а вместо этого создать ссылку на тот же экземпляр. – mandrake