Boost.Pythonを使用してC++クラスからPythonモジュールを作成しています。そして、私は参照に関する問題に遭遇しました。
値または参照のいずれかで返すことができるオーバーロードされたgetメソッドを持つクラスFooがある次のケースを考えてみてください。
署名をtypedefすると、値による戻り値を使用するように指定するのは簡単でした。ただし、を使用して参照を返すことも可能であると思います 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
;
}
注:生涯管理せずに既存のオブジェクトを参照することは危険である可能性があることを私は知っています。
更新:
オブジェクトでは機能するように見えますが、基本的なデータ型では機能しません。
この改訂された例を見てください:
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