[C++-sig] Re: Implicitly converting HeldTypes from Derived to Base?

David Abrahams dave at boost-consulting.com
Wed Aug 25 02:15:39 CEST 2004

Chad Austin <caustin at gmail.com> writes:

> I have a situation like this:
>     class_<A, APtr>("A");
>     class_<B, BPtr, bases<A> >("B");
>     def("foo", &foo);
>     // Without implicitly_convertible, foo(B()) fails with:
>     //
>     // Traceback (most recent call last):
>     //   File "<stdin>", line 1, in ?
>     // Boost.Python.ArgumentError: Python argument types in
>     //     foo.foo(B)
>     // did not match C++ signature:
>     //     foo(boost::intrusive_ptr<A>)
>     implicitly_convertible<BPtr, APtr>();
> }
> Is there any way that implicitly_convertible call from the Derived
> HeldType to the Base HeldType can be made automatic?

Not in general.  By the time 

  class_<B, BPtr, bases<A> >("B");

is uttered, there's no *compile-time* information linking APtr with A,
so there's no way to test for is_convertible<BPtr,APtr> ... and you
need to test that before you utter
implicitly_convertible<BPtr,APtr>().  Actually, without knowing about
APtr, you can't even say implicitly_convertible<BPtr,APtr>().

One possibility would be to extend Boost.Python to allow:

     class_<A, APtr>("A");
     class_<B, BPtr, bases<APtr> >("B");

That would be a kind of shorthand.

Another possibility would be to use partial specialization with
template template parameters to deduce that BPtr is actually
SomeTemplate<B>, and check for implicit convertibility from
SomeTemplate<B> to SomeTemplate<A>, and if that succeeds, then you can
utter implicitly_convertible<SomeTemplate<B>,SomeTemplate<A> >().
That would rely on the HeldTypes both being specializations of the
same template (admittedly likely) and on the compiler supporting both
aforementioned features.

The last approach is for all intents and purposes automatic.  It's
also a fair amount of work to implement.

Dave Abrahams
Boost Consulting

More information about the Cplusplus-sig mailing list