I have a method (or function) which returns a reference to a list of polymorphic objects:
class A {
};
class B : public A {
};
std::list<:shared_ptr> >& getList();
How do I expose such a function in boost::python so that when iterating on the list in python, I would see the different types of As and Bs ?
解决方案
First, make sure your classes are indeed polymorphic (i.e. they have at least one virtual function or a virtual destructor). Your example above doesn't, though I'm sure your real use case does. Without that none of Boost.Python's RTTI-based machinery for polymorphism will work.
Then, if you've exposed both classes with Boost.Python and registered shared_ptr converters for them:
#include
namespace bp = boost::python;
BOOST_PYTHON_MODULE(example) {
bp::class_("A");
bp::register_ptr_to_python< boost::shared_ptr >();
bp::class_< B, bp::bases >("B");
bp::register_ptr_to_python< boost::shared_ptr >();
}
...that's all you need to do to make sure Python only ever sees the most-derived type. There's no need to do anything special to ensure A is casted to B when possible.
That still leaves the question of how to wrap a function that returns a container. The simplest is probably to use the indexing suite included with Boost.Python:
There are other options floating around the web (including a "version 2" of the indexing suite that is better in many respects, but isn't included with Boost.Python), but for simple problems this is probably the most convenient.