Open
Description
In C++ clone pattern is used in many APIs:
class A {
public:
A();
A(const A& other)
virtual void func()=0;
virtual A* clone() const { return new A(*this); }
}
class A_trampoline: public A {
// Usual things for pure virtual func()
}
// function dependent on clone functionality
void work_on_many_instances(const shared_ptr<A>& inst){
std::vector<shared_ptr<A>> tasks;
for(int i=0; i<100; ++i) tasks.push_back( shared_ptr<A>(inst->clone()) );
// Do something with clonned instances
}
Suppose one extends class A in python using standard trampoline facilities and exposes it as usual:
py::class_<A,A_trampoline,std::shared_ptr<A>>(m, "A")
....
;
// Accepts PyObject with class derived in python from A
m.def("work_on_many_instances", [](const py::object& o){
auto p = o.cast<shared_ptr<A>>();
work_on_many_instances(p); // UPS! clone will try to create A, not the derived class...
});
When clone() is called inside work_on_many_instances() it creates an instance of A, which is an abstract class and, of course, fails. Unless I'm missing something obvious I can't figure out how to clone an object of derived class correctly. As far as I understand the trampoline should make a deep copy of existing python derived class instance on C++ side somehow but I have absolutely no idea how. Is it possible at all?