boost.python 对类似构造函数感到困惑

7 投票
1 回答
3307 浏览
提问于 2025-04-17 06:22

我有一个类,长得像这样:

class Foo{
    Foo();
    Foo(int i);
    Foo(bool b);
    Foo(double d);
};

然后我像往常一样把这个类暴露给Python使用。

class_<Foo>("Foo")
.def(init<int>())
.def(init<bool>())
.def(init<double>());

但是当我在Python中使用这个类时,Python代码总是把构造函数的参数转换成双精度浮点数(也就是类定义中最后一个参数的类型)。有没有办法明确告诉boost.python怎么根据类型来处理这些参数呢?

1 个回答

13

好吧,你可以改变构造函数的定义顺序,最后一个定义的优先级会更高。这里是我的结果:

class_<Foo>("Foo")
.def(init<bool>())
.def(init<double>())
.def(init<int>());

Foo() # calls Foo()
Foo(True) # calls Foo(int)
Foo(1) # calls Foo(int)
Foo(4.2) # calls Foo(double)

如你所见,这并不是一个完美的解决方案。所以,如果你真的需要让重载的构造函数正常工作,我建议你自己写一个工厂函数。

using namespace boost::python;

static boost::shared_ptr<Foo>
makeFoo(const object& data)
{
    boost::shared_ptr<Foo> obj;

    if (PyBool_Check(data.ptr())) {
        bool val = extract<bool>(data);
        obj.reset(new Foo(val));
    }
    else if (PyFloat_Check(data.ptr())) {
        double val = extract<double>(data);
        obj.reset(new Foo(val));
    }
    else {
        int val = extract<int>(data);
        obj.reset(new Foo(val));
    }

    return obj;
}

class_<Foo>("Foo")
    .def("__init__", make_constructor(makeFoo));

然后使用 makeFoo:

Foo() # calls Foo()
Foo(True) # calls Foo(bool)
Foo(1) # calls Foo(int)
Foo(4.2) # calls Foo(double)

顺便提一下,python.org上的文档可能会对你有点帮助。

撰写回答