Reputation: 972
Given this class
class ABC {
const std::string& getid() const;
/// other pure virtual methods
};
class D1 : public ABC {
/// override and implement virtual methods
};
class D2 : public ABC {
/// override and implement virtual methods
};
if I expose D1 and D2 to boost::python like so:
class_<D1, D1*>("D1", "...")
.def(getid, &ABC::getid)
;
the call from python to a D1 instance getid() triggers this error:
Boost.Python.ArgumentError: Python argument types in
D1.getid(D1)
did not match C++ signature:
getid(D1 {lvalue})
Is this to do const-correctness, with the implicit python self?
Upvotes: 0
Views: 78
Reputation: 2335
yes, this error is very much related to 'const-correctness'. the problem is your getid method is declared as const std::string& getid() const;
. it means not to modify it's state.
two possible solutions, first, overload getid such that boost will select the correct overload to avoid a wrapper.
you can add a non-const overload func for getid
class ABC {
public:
virtual std::string getid() = 0; //pure virtual, return just a '0'
const std::string& getid() const {
return 'ABC-id'; }
/// other pure virtual methods
virtual ~ABC() = default; //needed for polymorphism with boost::python
}
class D1 : public ABC {
public:
/// override and implement virtual methods
std::string getid() override { //return the id for D1
return 'D1';
}
class D2 : public ABC {
public:
/// override and implement virtual methods
std::string getid() override {
//return the id for D2.
return 'D2';
}
};
imo, overloading the getid function is straight forward than a wrapper class.
UPDATE: expose it like this,
class_<ABC, boost::noncopyable>("ABC"); //now it's baseclass, no copying
class_<D1, boost::python::bases<ABC>, D1*>("D1")
.def("getid", &ABC::getid) // this will the correct overload now
;
same for class D2.
Upvotes: -1