Ste*_*hen 8 c++ python boost-python
我用boost-python包装C++类,我想知道有没有比我现在做的更好的方法.
问题是这些类具有相同名称的getter/setter,并且似乎没有用boost-python包装它的无痛方法.
这是问题的简化版本.鉴于此类:
#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;
};
Run Code Online (Sandbox Code Playgroud)
我想做的事情如下:
BOOST_PYTHON_MODULE(foo)
{
class_<Foo>("Foo", init<>())
.add_property("x", &Foo::x, &Foo::x)
;
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为boost-python无法确定要使用的函数版本.
事实上,你甚至做不到
.def("x", &Foo::x)
Run Code Online (Sandbox Code Playgroud)
出于同样的原因.
我正在重新阅读boost.org上的教程,有关重载的部分似乎非常有前途.不幸的是,它似乎并不是我想要的.
在重载部分,它提到了一个BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS像这样工作的宏:
如果有另一个成员函数,则Foo使用默认参数:
void z(int i=42)
{
std::cout << i << "\n";
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用宏:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(z_member_overloads, z, 0, 1)
Run Code Online (Sandbox Code Playgroud)
然后在BOOST_PYTHON_MODULE:
.def("z", &Foo::z, z_member_overloads())
Run Code Online (Sandbox Code Playgroud)
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())
Run Code Online (Sandbox Code Playgroud)
不编译:
error: no matching member function for call to 'def'
.def("x", &Foo::x, x_member_overloads())
~^~~
Run Code Online (Sandbox Code Playgroud)
问题: 那么,是否有其他宏可以使这项工作成功?
为了完整性,我正在处理这样的案例:
.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>()
)
)
Run Code Online (Sandbox Code Playgroud)
您可以通过强制转换为适当的重载(未经测试)来做到这一点:
class_<Foo>("Foo", init<>())
.add_property("x",
static_cast< double(Foo::*)() const >(&Foo::x), // getter
static_cast< void(Foo::*)(const double) >(&Foo::x)) // setter
;
Run Code Online (Sandbox Code Playgroud)