Boost python getter/setter 同名

Posted

技术标签:

【中文标题】Boost python getter/setter 同名【英文标题】:Boost python getter/setter with the same name 【发布时间】:2017-05-28 20:22:45 【问题描述】:

我正在用 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 上重新阅读了教程,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,它会向 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>()
        )
    )

【问题讨论】:

【参考方案1】:

您可以通过强制转换为适当的重载来做到这一点(未经测试):

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 getter/setter 同名的主要内容,如果未能解决你的问题,请参考以下文章

java 集合排序

ImageView显示图像控件

java集合进行排序的两种方式

boost.build 与 boost.python

将 boost::python::numpy::ndarray 作为 boost::python 函数的(默认与否)参数传递?

Boost.Python 创建的 dll 无法导入(遵循 Boost Python 的 QuickStart)