[C++-sig] Re: Automatic downcast question

David Abrahams dave at boost-consulting.com
Mon Jun 16 02:16:00 CEST 2003

"Stefan Franke" <franke at ableton.com> writes:

>> -----Original Message-----
>> From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On
>> Behalf Of David Abrahams
> ...
>> I think it's reasonable to try to convert directly to the actual type
>> of the pointee (C), but I don't think it's reasonable to try
>> downcasting to every known derived class of the pointee's static type.
> But "every known derived class" is not what I was asking for. Rather
> "the lowermost class on the inheritance graph from the pointee's static
> type to its actual type that has been registered to BPL via
> bases<>".
> (Sorry if my English is weird).

Nothing wrong with your English, but:

  1. That type may not exist:

         / \
        B   C
         \ /
          D     <- not registered

  2. There's no way to implement that in C++ without potentially
     trying conversions to every known (i.e. registered) derived class
     of the pointee's static type.  

> This is typically exactly one class (B), unless with diamond-shaped
> inheritance. In this case a non-ambivalent base class could be
> chosen.

You must mean non-ambiguous. 

If you can provide a reasonably-efficient implementation, I'm all for
it.  However #1, I'm fairly sure that there is no implementation
that's reasonably efficient in general (meaning only has to do a small
number of dynamic_cast<>s.  However #2, I'm not sure that people care
all that much about efficiency in cases like these.  However #3, it's
possible to do the inefficient search for a "most-derived wrapped
type" once and cache the result.

Option 3 would integrate best with what's already happening in
inheritance.hpp/.cpp, but I don't think I have time to implement it
right now.

>> We could consider implementing that as a new return value policy,
>> though, so you can ask for it when you need it.
> Another option (at least for me) would be to be able to dynamically
> cast a wrapped A to a wrapped C instance. Is that possible?

?? I thought the whole point of this was that C wasn't wrapped?

Dynamically casting A->B is pretty simple; just wrap this:

      object asB(back_reference<B&> b) { return b.source(); }

Dave Abrahams
Boost Consulting

More information about the Cplusplus-sig mailing list