I have a class that looks like
class Foo{
Foo();
Foo(int i);
Foo(bool b);
Foo(double d);
};
and I expose my class to python as usual
class_<Foo>("Foo")
.def(init<int>())
.def(init<bool>())
.def(init<double>());
when I try to use to in python, the python code always cast the c'tor parameter into double (which is always the last one in the class def export). Is there a way to explicit tell boost.python how to explicitly handle by the type?
Well, you can change the order of constructor's definitions, the last one will have higher priority. Here is my results:
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)
As you see, it's not a perfect solution. So, if you really need to make overloaded constructors work I suggest to roll your own factory function.
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));
And using makeFoo:
Foo() # calls Foo()
Foo(True) # calls Foo(bool)
Foo(1) # calls Foo(int)
Foo(4.2) # calls Foo(double)
By the way, docs at python.org can be somewhat helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With