Boost Python: polymorphic container?

安稳与你 提交于 2019-12-05 00:14:20


I have a method (or function) which returns a reference to a list of polymorphic objects:

class A {

class B : public A {


std::list<boost::shared_ptr<A> >& 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 <boost/python.hpp>

namespace bp = boost::python;

    bp::class_<A >("A");
    bp::register_ptr_to_python< boost::shared_ptr<A> >();
    bp::class_< B, bp::bases<A> >("B");
    bp::register_ptr_to_python< boost::shared_ptr<B> >();

...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.