Boost python getter/setter 同名
Boost python getter/setter with the same name
我正在用 boost-python 包装 C++ classes,我想知道是否有比我现在做的更好的方法。
问题是 classes 有 getters/setters 同名,似乎没有一种轻松的方法可以用 boost-python 包装它。
这是问题的简化版本。鉴于此 class:
#include <boost/python.hpp>
using namespace boost::python;
class Foo {
public:
double
x() const
{
return _x;
}
void
x(const double new_x)
{
_x = new_x;
}
private:
double _x;
};
我想做这样的事情:
BOOST_PYTHON_MODULE(foo)
{
class_<Foo>("Foo", init<>())
.add_property("x", &Foo::x, &Foo::x)
;
}
这不起作用,因为 boost-python 无法确定要使用哪个版本的函数。
事实上,你甚至做不到
.def("x", &Foo::x)
出于同样的原因。
我正在重读 boost.org 上的教程,section on overloading 看起来很有前途。不幸的是,这似乎不是我要找的。
在重载部分,它提到了一个 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
宏,其工作方式如下:
如果 Foo
中有另一个成员函数采用默认参数:
void z(int i=42)
{
std::cout << i << "\n";
}
然后您可以使用宏:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(z_member_overloads, z, 0, 1)
然后在 BOOST_PYTHON_MODULE
:
.def("z", &Foo::z, z_member_overloads())
z_member_overloads
允许您调用 def
一次,它会将 0 个参数和 1 个参数的方法公开给 python。
我希望这对我的 x()
和 x(double val)
getter/setter 有用,但它不起作用。
正在做:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(x_member_overloads, x, 0, 1)
...
.def("x", &Foo::x, x_member_overloads())
不编译:
error: no matching member function for call to 'def'
.def("x", &Foo::x, x_member_overloads())
~^~~
问题:
那么,是否有另一个宏或其他东西可以使这个工作?
为了完整起见,这就是我目前处理此类案件的方式:
.add_property(
"x",
make_function(
[](Foo& foo) {
return foo.x();
},
default_call_policies(),
boost::mpl::vector<double, Foo&>()
),
make_function(
[](Foo& foo, const double val) {
foo.x(val);
},
default_call_policies(),
boost::mpl::vector<void, Foo&, double>()
)
)
您可以通过转换为适当的重载(未经测试)来做到这一点:
class_<Foo>("Foo", init<>())
.add_property("x",
static_cast< double(Foo::*)() const >(&Foo::x), // getter
static_cast< void(Foo::*)(const double) >(&Foo::x)) // setter
;
我正在用 boost-python 包装 C++ classes,我想知道是否有比我现在做的更好的方法。
问题是 classes 有 getters/setters 同名,似乎没有一种轻松的方法可以用 boost-python 包装它。
这是问题的简化版本。鉴于此 class:
#include <boost/python.hpp>
using namespace boost::python;
class Foo {
public:
double
x() const
{
return _x;
}
void
x(const double new_x)
{
_x = new_x;
}
private:
double _x;
};
我想做这样的事情:
BOOST_PYTHON_MODULE(foo)
{
class_<Foo>("Foo", init<>())
.add_property("x", &Foo::x, &Foo::x)
;
}
这不起作用,因为 boost-python 无法确定要使用哪个版本的函数。
事实上,你甚至做不到
.def("x", &Foo::x)
出于同样的原因。
我正在重读 boost.org 上的教程,section on overloading 看起来很有前途。不幸的是,这似乎不是我要找的。
在重载部分,它提到了一个 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
宏,其工作方式如下:
如果 Foo
中有另一个成员函数采用默认参数:
void z(int i=42)
{
std::cout << i << "\n";
}
然后您可以使用宏:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(z_member_overloads, z, 0, 1)
然后在 BOOST_PYTHON_MODULE
:
.def("z", &Foo::z, z_member_overloads())
z_member_overloads
允许您调用 def
一次,它会将 0 个参数和 1 个参数的方法公开给 python。
我希望这对我的 x()
和 x(double val)
getter/setter 有用,但它不起作用。
正在做:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(x_member_overloads, x, 0, 1)
...
.def("x", &Foo::x, x_member_overloads())
不编译:
error: no matching member function for call to 'def'
.def("x", &Foo::x, x_member_overloads())
~^~~
问题: 那么,是否有另一个宏或其他东西可以使这个工作?
为了完整起见,这就是我目前处理此类案件的方式:
.add_property(
"x",
make_function(
[](Foo& foo) {
return foo.x();
},
default_call_policies(),
boost::mpl::vector<double, Foo&>()
),
make_function(
[](Foo& foo, const double val) {
foo.x(val);
},
default_call_policies(),
boost::mpl::vector<void, Foo&, double>()
)
)
您可以通过转换为适当的重载(未经测试)来做到这一点:
class_<Foo>("Foo", init<>())
.add_property("x",
static_cast< double(Foo::*)() const >(&Foo::x), // getter
static_cast< void(Foo::*)(const double) >(&Foo::x)) // setter
;