[C++-sig] can these exports be avoided

David Abrahams dave at boostpro.com
Mon Nov 10 23:43:13 CET 2008


on Mon Nov 10 2008, Gennadiy Rozental <rogeeff-AT-gmail.com> wrote:

> Simple scenario:
>
> class IObject {};
>
> class Base : public IObject {
> public:
>    virtual void foo() {}
> };
>
> class Derived : public Base {
>    virtual void foo() {}
> };
>
> Both IObject and Base are exported into Python:
>
> bp::class_<IObject,noncopyable>( "IObject", bp::no_init );
>
> bp::class_<Base,bp::bases<IObject>,noncopyable>( "Base", bp::no_init )
>    .def( "foo", &Base::foo );
>
> Also imagine I've got function like this:
>
> IObjectPtr
> create( std::string const& class_name )
> {
> ...
>   if(class_name=="Derived")
>      return IObjectPtr(new Derived);
> }
>
> and this function is also exported into Python.
>
> Now in Python I've got code like this:
>
> o = mymodule.create( "Derived" );
> print type(o)
>
> As it stands above print statement produces "mymodule.IObject". What would be
> preferable if it can produce mymodule.Base, so I can invoke method foo.
>
> It can be resolved with additional export for class Derived:
>
> bp::class_<Derived,bp::bases<Base>,noncopyable>( "Derived", bp::no_init );
>
> In which case above print statement starts to show mymodule.Derived. But I would
> really prefer to avoid these exports for derived classes. After all RTTI
> information should shoe Boost.Python whole hierarchy, isn't it? Why can't it
> figure out that pointer produced by create actually convertible to Base*, even
> though it knows nothing about Derived?

It could, if we were willing to search the DAG of known classes rooted
at Base.  I always thought that would be terrible, but maybe
not... after all, you can do it one level at a time.  If you enter a
ticket, I'll look into it.  Please attach a minimal example.

> Does any one have any workarounds?

You found the only one I know of: register Derived.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com


More information about the Cplusplus-sig mailing list