[C++-sig] preventing a copy of the vector when using the vector_indexing_suite

Scott McKay skottmckay at gmail.com
Thu Aug 11 03:03:12 CEST 2005


> You've left out a lot of detail, but if you want to pass something
> from C++ to Python by reference, you need to wrap it in boost::ref( )
> Otherwise, Boost.Python will take the safe route and pass it by value.

Sorry - was trying to keep it to the essential details. 

I tried adding the boost:ref() call and that corrects the copy and
provides a reference to the vector in the python code, however it
fails when exiting from the python class' (TestExtendedFactory)
generate method with

'TypeError: No registered converter was able to extract a C++
reference to type Factory from this Python object of type
TestExtendedFactory'

Do I need to register a custom converter, or is there some other call
I'm missing to connect the python object with its base class'
converters?

Thanks for you help so far.

S

Here's a fuller picture:

--- boost python code, largely created by Pyste

--- Abstract base class for the Factory 

struct Factory_Wrapper: Factory, wrapper< Factory >
{
    Factory_Wrapper(const Factory& p0):
        Factory(p0) {}

    Factory_Wrapper():
        Factory() {}

    Factory& generate(std::vector<smart_ptr<X>>& p0) {
        boost::ref( p0 );
        if (override f = this->get_override("generate"))
            return call< Factory& >( f.ptr(), p0);
        return Factory::generate(p0);
    }

    Factory& default_generate(std::vector<smart_ptr<X>>& p0) {
        return Factory::generate(p0);
    }
};

void Export_SourceFactory()
{
    class_< Factory_Wrapper, smart_ptr< Factory_Wrapper > >("Factory",
init<  >())
        .def("generate", &Factory::generate,
&Factory_Wrapper::default_generate, return_self<>())
        .def(init< const Factory& >())
    ;

    implicitly_convertible< smart_ptr< Factory_Wrapper >, smart_ptr<
Factory > >();
}


--- Basic version of the factory - implemented in C++

struct BasicFactory_Wrapper: BasicFactory, wrapper< BasicFactory >
{
    BasicFactory_Wrapper(const BasicFactory& p0):
        BasicFactory(p0) {}

    BasicFactory_Wrapper(DocId p0, const Profile& p1):
        BasicFactory(p0, p1) {}

    Factory& generate(std::vector<smart_ptr<X>>& p0) {
        boost::ref( p0 );
        if (override f = this->get_override("generate"))
            return call< Factory& >( f.ptr(), p0);
        return BasicFactory::generate(p0);
    }

    Factory& default_generate(std::vector<smart_ptr<X>>& p0) {
        return BasicFactory::generate(p0);
    }

};

--- Class to export the basic factory

void Export_BasicFactory()
{
    class_< BasicFactory_Wrapper, smart_ptr< BasicFactory_Wrapper >
>("BasicFactory", init< >())
        .def("generate", (Factory&
(BasicFactory::*)(std::vector<smart_ptr<X>>&)
)&BasicFactory::generate, (Factory&
(BasicFactory_Wrapper::*)(std::vector<smart_ptr<X>>&))&BasicFactory_Wrapper::default_generate,
return_self<>())
        .def(init< const BasicFactory& >())
    ;

   implicitly_convertible< smart_ptr< BasicFactory_Wrapper >,
smart_ptr< BasicFactory > >();
   implicitly_convertible< smart_ptr< BasicFactory >, smart_ptr< Factory > >();
}

In the C++ code the section that calls Factory->generate holds the
Factory in a smart_ptr, FWIW.

The python code goes like...

class TestExtendedFactory( s.BasicFactory ):
    "Example showing how to provide your own snippet factor for
initial snippet selection"

    def __init__( self ):

        # call init of parent to setup smart pointers correctly
        super( TestExtendedFactory, self ).__init__()
        
        
    def generate( self, vectorOfSmartPtrs ):

        # call BasicFactory's generate
        super( TestExtendedFactory, self ).generate( vectorOfSmartPtrs )



More information about the Cplusplus-sig mailing list