No automatic upcasting with std::shared_ptr in function calls?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

No automatic upcasting with std::shared_ptr in function calls?

Václav Šmilauer
Hello,

I have a sample hierarchy of polymorphic classes (A from which B inherits).
One of them (A1, B1) is managed with boost::shared_ptr, the other one
(A2, B2) via std::shared_ptr (I defined the get_pointer template for
std::shared_ptr).

When I call f1(boost::shared_ptr<A1>) with an object B1 from python,
it is correctly upcast to the pointer to its base class and the c++
function is called. When I call f2(std::shared_ptr<A2>) with B2 argument
from python, no upcasting takes place and I get Boost.Python.Argument
error.

The code is here:

foo.cpp:

#include<boost/shared_ptr.hpp>
/// make boost::python understand std::shared_ptr
#include<memory>
namespace boost {
   template<class T> T* get_pointer(std::shared_ptr<T> p){ return p.get(); }
}

// define a hierarchy
struct A1{ virtual ~A1(){} };
struct B1: public A1{ virtual ~B1(){} };
void f1(boost::shared_ptr<A1> ptr){ std::cerr<<"f1()"<<std::endl; }

struct A2{ virtual ~A2(){} };
struct B2: public A2{ virtual ~B2(){} };
void f2(std::shared_ptr<A2> ptr){ std::cerr<<"f2()"<<std::endl; }

#include<boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(foo){
   class_<A1,boost::shared_ptr<A1>>("A1");
   class_<B1,boost::shared_ptr<B1>,bases<A1>>("B1");
   def("f1",f1);
   class_<A2,std::shared_ptr<A2>>("A2");
   class_<B2,std::shared_ptr<B2>,bases<A2>>("B2");
   def("f2",f2);
}

compiling with (under Linux):

  g++ -std=c++0x foo.cpp -o foo.so -fPIC -shared -lboost_python
  `pkg-config python --libs --cflags`

Running

  PYTHONPATH=. python -c "import foo; foo.f1(foo.B1()); foo.f2(foo.B2());"

I obtain:

  f1()
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  Boost.Python.ArgumentError: Python argument types in
      foo.f2(B2)
  did not match C++ signature:
      f2(std::shared_ptr<A2>)

Where is the problem?

Cheers, Vaclav

_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: No automatic upcasting with std::shared_ptr in function calls?

Jim Bosch-2
On 04/20/2012 03:55 AM, VáclavŠmilauer wrote:

> Hello,
>
> I have a sample hierarchy of polymorphic classes (A from which B inherits).
> One of them (A1, B1) is managed with boost::shared_ptr, the other one
> (A2, B2) via std::shared_ptr (I defined the get_pointer template for
> std::shared_ptr).
>
> When I call f1(boost::shared_ptr<A1>) with an object B1 from python,
> it is correctly upcast to the pointer to its base class and the c++
> function is called. When I call f2(std::shared_ptr<A2>) with B2 argument
> from python, no upcasting takes place and I get Boost.Python.Argument
> error.
>

<snip>

>
> Where is the problem?
>

I'm pretty sure this is a symptom of the fact that boost::shared_ptr is
handled specially by Boost.Python, and custom smart pointers (which is
what std::shared_ptr is considered in this case) don't have all the same
features.  In particular, Boost.Python doesn't assume that custom smart
pointers have implicit upcast converters, which would be needed to do
what you want (note that some smart pointers, like boost::scoped_ptr,
don't have implicit upcast converters).

The good news is that there's an easy workaround.  You just need to tell
Boost.Python that the implicit conversion exists:

implicitly_convertible<std::shared_ptr<B2>,std::shared_ptr<A2>>();

That was enough to get your example to work for me.


Jim
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Loading...