std::tr1::shared_ptr as boost::shared_ptr
Hello, I am exposing a C++ app, which makes heavy use of tr1::shared_ptr, which seems to be exactly(?) the same as boost::shared_ptr. I have managed to make most of the stuff work just as it would be boost::shared_ptr ( additionally adding support for shared_ptr<const T> - thanks to [1] ): namespace my_app_namespace { //Make Boost.Python work with std::tr1::shared_ptr<> template<typename T_> inline T_ * get_pointer(std::tr1::shared_ptr<T_> const & p) { return p.get(); } //Make Boost.Python work with std::tr1::shared_ptr<const> template<typename T_> inline T_ * get_pointer(std::tr1::shared_ptr<const T_> const & p) { return const_cast<T_*>(p.get()); } } namespace boost { namespace python { //Make Boost.Python work with std::tr1::shared_ptr<> template<typename T_> struct pointee<std::tr1::shared_ptr<T_> > { typedef T_ type; }; //Make Boost.Python work with std::tr1::shared_ptr<const> template<typename T_> struct pointee<std::tr1::shared_ptr<const T_> > { typedef T_ type; }; } } What is still not working is the implicit conversion of Foo and Derived for functions taking std::tr1::shared_ptr<Foo>. With boost::shared_ptr it just works when you add the bp::bases<Foo> to the Derived: func(boost::shared_ptr<Foo>) ... bp::class_<Foo> ... bp::class_<Derived, bp::bases<Foo> > ... and func can take both Foo and Derived. But with std::tr1::shared_ptr I have to use: func(std::tr1::shared_ptr<Foo>) ... bp::class_<Foo, std::tr1::shared_ptr<Foo> > ... bp::class_<Derived, std::tr1::shared_ptr<Derived>, bp::bases<Foo> > ... bp::implicitly_convertible<std::tr1::shared_ptr<Foo>, std::tr1::shared_ptr<Derived> >(); How can I make it working just as with boost::shared_ptr? Btw. I have seen [2] already, but it doesn't seem to cover that. [1] - http://language-binding.net/pyplusplus/troubleshooting_guide/shared_ptr/shar... [2] - http://language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smar... -- Best Regards, Piotr Jaroszynski
On 4/20/07, Piotr Jaroszynski <p.jaroszynski@gmail.com> wrote:
bp::class_<Foo, std::tr1::shared_ptr<Foo> > ... bp::class_<Derived, std::tr1::shared_ptr<Derived>, bp::bases<Foo> > ... bp::implicitly_convertible<std::tr1::shared_ptr<Foo>, std::tr1::shared_ptr<Derived> >();
How can I make it working just as with boost::shared_ptr?
There is no implicit conversion from a base class to the dervied. The other way will work: bp::implicitly_convertible<std::tr1::shared_ptr<Derived>, std::tr1::shared_ptr<Foo> >();
Btw. I have seen [2] already, but it doesn't seem to cover that.
It does :-)
[1] -
http://language-binding.net/pyplusplus/troubleshooting_guide/shared_ptr/shar...
[2] -
http://language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smar... Glad you found this useful
-- Best Regards, Piotr Jaroszynski
-- Roman Yakovenko C++ Python language binding http://www.language-binding.net/
On Friday 20 of April 2007 18:53:32 Roman Yakovenko wrote:
There is no implicit conversion from a base class to the dervied. The other way will work:
bp::implicitly_convertible<std::tr1::shared_ptr<Derived>, std::tr1::shared_ptr<Foo> >();
Err I made a "typo", that's what I meant as a work around. What I asked about was whether it's possible to make it work exactly as with boost::shared_ptr, so: func(std::tr1::shared_ptr<Foo>) ... bp::class_<Foo> ... bp::class_<Derived, bp::bases<Foo> > ... and func can take both Foo and Derived. I suppose it's a matter of making some "mirror" templates for std::tr1::shared_ptr so boost.python will treat it exactly as it treats boost::shared_ptr. -- Best Regards, Piotr Jaroszynski
On 4/20/07, Piotr Jaroszynski <p.jaroszynski@gmail.com> wrote:
On Friday 20 of April 2007 18:53:32 Roman Yakovenko wrote:
There is no implicit conversion from a base class to the dervied. The other way will work:
bp::implicitly_convertible<std::tr1::shared_ptr<Derived>, std::tr1::shared_ptr<Foo> >();
Err I made a "typo", that's what I meant as a work around. What I asked about was whether it's possible to make it work exactly as with boost::shared_ptr, so: func(std::tr1::shared_ptr<Foo>) ... bp::class_<Foo> ... bp::class_<Derived, bp::bases<Foo> > ...
and func can take both Foo and Derived.
I suppose it's a matter of making some "mirror" templates for std::tr1::shared_ptr so boost.python will treat it exactly as it treats boost::shared_ptr.
I am not sure. What you can do is to search Boost.Python library for shared_ptr usage. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/
On Friday 20 of April 2007 19:26:43 Roman Yakovenko wrote:
I am not sure. What you can do is to search Boost.Python library for shared_ptr usage.
If you are not sure then there is only one person left :] I will love your input David and tia! In the meantime I will indeed try searching the library... -- Best Regards, Piotr Jaroszynski
Piotr Jaroszynski wrote:
Hello,
I am exposing a C++ app, which makes heavy use of tr1::shared_ptr, which seems to be exactly(?) the same as boost::shared_ptr. I have managed to make most of the stuff work just as it would be boost::shared_ptr ( additionally adding support for shared_ptr<const T> - thanks to [1] ):
Btw. I have seen [2] already, but it doesn't seem to cover that.
[1] - http://language-binding.net/pyplusplus/troubleshooting_guide/shared_ptr/shar... [2] - http://language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smar...
Hi, I've got the same problem. Basically, given class A { ... }; class B : public A { ... }; It seems that Boost.Python is always able to call void foo(const boost::shared_ptr<B> & x); with and argument of type OTHER_SMART_PTR<A> How is it possile? I would like to achieve the same with my own smart pointer. I've tried with tr1::shared_ptr, my own smart pointer, the *exact* same code as boost::shared_ptr copied with a different name... It looks like boost::shared_ptr is *much* more powerful than all other smart pointers that can be registered. Here is the code. How you can see, I never tell Boost.Python anything about boost::shared_ptr. Then you can run the following python code
import bo b=bo.newB(10) print bo.getI_OK(b) 30 print bo.getI_FAIL(b) Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in bo.getI_FAIL(B) did not match C++ signature: getI_FAIL(std::tr1::shared_ptr<B>)
It seems that Boost.Python can extract the object from my smart pointer, dynamic_cast it to the right type and create a boost::shared_pointer. Just how...? ============================================================================================================= #include <boost/python.hpp> #include <boost/shared_ptr.hpp> #include <tr1/memory> using namespace boost::python; #define OTHER_PTR std::tr1::shared_ptr // needed by Boost.Python template<class T> T * get_pointer(OTHER_PTR<T> const & p) { return p.get(); } class A { public: A(int i) : myInt(i) {} virtual ~A() {} virtual int getI() const { return myInt * 2; } protected: int myInt; }; class B : public A { public: B(int i) : A(i) {} virtual int getI() const { return myInt * 3; } }; // how is it possible that Boost.Python knows how to create a boost::shared_ptr<B>? // basically it can convert a OTHER_PTR<A> (as returned by newB) to a boost::shared_ptr<B> needed here int getI_OK(const boost::shared_ptr<B> & a) { return a->getI(); } // but it cannot do it here int getI_FAIL(const OTHER_PTR<B> & a) { return a->getI(); } OTHER_PTR<A> newB(int i) { return OTHER_PTR<A>(new B(i)); } BOOST_PYTHON_MODULE(bo) { def("newB", newB); def("getI_OK", getI_OK); def("getI_FAIL", getI_FAIL); class_<A> ("A", no_init); class_<B, bases<A> >("B", no_init); register_ptr_to_python<OTHER_PTR<A> >(); } ============================================================================================================ Andrea
participants (3)
-
Andrea -
Piotr Jaroszynski -
Roman Yakovenko