Boost python getter/setter with the same name

Boost python getter/setter with the same name

本文关键字:the same name with setter python getter Boost      更新时间:2023-10-16

我正在用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;
};

我想做这样的事情:

BOOST_PYTHON_MODULE(foo)
{
class_<Foo>("Foo", init<>())
.add_property("x", &Foo::x, &Foo::x)
;
}

这是行不通的,因为 boost-python 无法确定要使用哪个版本的函数。

事实上,你甚至做不到

.def("x", &Foo::x)

出于同样的原因。

我在 boost.org 重新阅读了教程,关于重载的部分似乎非常有前途。不幸的是,这似乎不是我想要的。

在重载部分,它提到了一个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一次,它将向 python 公开 0 参数和 1 参数的方法。

我希望这对我的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
;
相关文章: