[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