custom smart pointer, vector_indexing_suite typeerror
Is the following possible or am I doing something wrongly? I have a custom smart pointer, and an abstract base class that is wrapped specifying smart_ptr<X> as the HeldType, as I want to treat the object as if it's automatically wrapped with a smart_ptr. I then have a std::vector<smart_ptr<X>> exposed using the vector_indexing_suite with proxying turned off. Basically something along these lines... struct X_Wrapper: X { X_Wrapper(PyObject* py_self_): X(), py_self(py_self_) {} X& run() { return call_method< X& >(py_self, "run"); } } class_< X, X_Wrapper, boost::noncopyable, smart_ptr< X > >("X", init<>()) .def("run", pure_virtual(&X::run), return_self<>()) ; class_< std::vector< smart_ptr<X> > > ( "vector_X" ) .def( vector_indexing_suite< std::vector< smart_ptr<X> >, true >() ) ; Then in the python code I want to implement the X interface and add the python object that does so to the vector. class testX( X ): def run( self ): print "run" return self tester = testX() vector = vector_X() vector.append( tester ) Doing so leads to a type error in the append (from the base_append of the vector_indexing_suite). The object type is a 'testX', which I thought would be held as a smart_ptr<X> under the covers and hence would be convertible, but I guess that isn't the case. As the vector takes a non-const I thought it was necessary to use the HeldType rather than register_ptr_to_python. Is there a way to make this work? I'm not sure I have everything setup correctly though, so perhaps I'm missing a piece. Thanks for any help. Scott
After some experimentation/review I think this
class_< X, X_Wrapper, boost::noncopyable, smart_ptr< X > >("X", init<>()) .def("run", pure_virtual(&X::run), return_self<>()) ;
should be class_<X,boost::noncopyable,smart_ptr<X_wrapper> >("X", init<>()) ... However doing so still results in a TypeError. Now if I make it a vector of boost::shared_ptr<X>'s, I can append a testX to it, so I'm thinking it may be due to the 'smart' pointer class not being able to handle the conversion between X_Wrapper and X. Could that be the case? Thanks S
Scott McKay <skottmckay@gmail.com> writes:
Is the following possible or am I doing something wrongly?
I have a custom smart pointer, and an abstract base class that is wrapped specifying smart_ptr<X> as the HeldType, as I want to treat the object as if it's automatically wrapped with a smart_ptr.
I then have a std::vector<smart_ptr<X>> exposed using the vector_indexing_suite with proxying turned off.
Basically something along these lines...
struct X_Wrapper: X { X_Wrapper(PyObject* py_self_): X(), py_self(py_self_) {}
X& run() { return call_method< X& >(py_self, "run"); } }
You should use the new-style polymorphism support (http://www.boost.org/libs/python/doc/v2/wrapper.html) although this probably has nothing to do with your problem.
class_< X, X_Wrapper, boost::noncopyable, smart_ptr< X > >("X", init<>()) .def("run", pure_virtual(&X::run), return_self<>()) ;
class_< std::vector< smart_ptr<X> > > ( "vector_X" ) .def( vector_indexing_suite< std::vector< smart_ptr<X> >, true >() ) ;
Then in the python code I want to implement the X interface and add the python object that does so to the vector.
class testX( X ):
def run( self ):
print "run" return self
tester = testX() vector = vector_X() vector.append( tester )
Doing so leads to a type error in the append (from the base_append of the vector_indexing_suite). The object type is a 'testX', which I thought would be held as a smart_ptr<X> under the covers and hence would be convertible, but I guess that isn't the case.
The problem is that you're missing an __init__ function in testX. Calling the __init__ function of the base class inside it (i.e. X.__init__(self)) is what causes the held smart_ptr<X> to be created.
As the vector takes a non-const I thought it was necessary to use the HeldType rather than register_ptr_to_python.
I'm not sure they're related.
Is there a way to make this work? I'm not sure I have everything setup correctly though, so perhaps I'm missing a piece.
I think the __init__ function will do it for you. -- Dave Abrahams Boost Consulting www.boost-consulting.com
You should use the new-style polymorphism support (http://www.boost.org/libs/python/doc/v2/wrapper.html) although this probably has nothing to do with your problem.
I'll check it out. Thanks
The problem is that you're missing an __init__ function in testX. Calling the __init__ function of the base class inside it (i.e. X.__init__(self)) is what causes the held smart_ptr<X> to be created.
Ahh. Didn't realize the __init__ was required to trigger that. I did have it 'working' without the init after I added an implicitly_convertible< < smart_ptr<X_Wrapper>, smart_ptr<X> >(). It would append but I hadn't verified that all the reference counting was working as expected. I will add the __init__ as well. Many thanks for your help. Scott
participants (2)
-
David Abrahams -
Scott McKay