[C++-sig] automatic downcasting with V2

David Abrahams dave at boost-consulting.com
Thu Dec 19 02:18:21 CET 2002

"Daniel Paull" <dlp at fractaltechnologies.com> writes:

> Hi all,
> I followed a thread entitled "Python + Boost Python V2 + downcasting"
> from the start of November this year.  I have a similar problem and am
> wondering what the final solution was and whether it has been
> incorporated into boost.python yet.

Well, I said I was going to do something about it, but then never
actually did ;-)

I'll see if I can whip something together.

In the meantime, here's a question I'd like you and Nicolas to try to
answer.  Suppose I have:

    struct A { virtual ~A(); };
    struct B : A {};
    struct C : B {};

    A* factory(int x) { return x == 0 ? new A : x == 1 ? new B : new C; }


    #include <boost/python.hpp>
    using namespace boost::python;
        def("factory", factory, return_value_policy<manage_new_object>());

        class_<B, bases<B> >("B");
        // note, C not registered.

Now, clearly:
    >>> from test import *
    >>> type(factory(0))

And, after my changes:

    >>> type(factory(1))

But, what's the result of:

    >>> type(factory(2))


It's easy enough to acheive "test.A".

If you want it to be "test.B", my job is harder.  It's easy enough to
say "just find the most-derived type which is registered".  But even
in a single-inheritance hierarchy, that is not easy to do efficiently.

Furthermore, C++ inheritance hierarchies in general form a DAG.  If
the actual type of the object isn't registered, there may not be any
single most-derived type which is registered:

      / \
     B   C  <= B and C are registered
      \ /
       D    <= D is not.

So, what about cases like this one?

                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

More information about the Cplusplus-sig mailing list