What I need is a way to tell boost python that anytime it needs to convert a ptr<Base> to python it should first convert it to a ref_ptr<Base> (using a standard copy constructor in ref_ptr<>) and then use this ref_ptr as the held type like normal.
At first I thought that implicitly_convertible<> would help:
implicitly_convertible<ptr<Base>, ref_ptr<Base> >();
But this doesn't seem to do anything for me. (this really isn't too surprising since this isn't what implicitly_convertible is for, but it seemed worth a try).
Has anyone else ran into anything similar? Any ideas?
At first glance, it seems like you want to register a to-python conversion for all your ptr<T> types. Note that all code I write in this message is untested: template <class T> struct ptr_to_python { static PyObject *convert(ptr<T> const &p) { return Py_INCREF(object(ref_ptr<T>(p)).ptr()); } }; Then you need to do this for each class you register: to_python_converter<ptr<T>, ptr_to_python<T> >(); You could automate this in a custom def visitor: struct ref_ptr_stuff : def_visitor<ref_ptr_stuff> { friend class def_visitor_access; template <typename Class> void visit(Class &c) const { typedef typename Class::wrapped_type T; to_python_converter<ptr<T>, ptr_to_python<T> >(); } }; Then when you wrap your classes you can say: class<T, bases<...>, ref_ptr<T> >("T",...) .def(ref_ptr_stuff()) Note that this gives you a convenient way to put common methods on all ref_ptr types. For example, you could .def() a method that returns the ref count in the ref_ptr_stuff visitor. Also note that when you get to doing polymorphic wrappers, you're going to want to be able to distinguish the polymorphic wrapper type from the "logical" wrapped type T. To do that, you'll need to either roll your own or be willing to use non-public boost.python api. (detail::unwrap_wrapper). Hope that helps, Alex