3

I would like to know how classes A and B below can work polymorphically in python when using std::shared_ptr instead of boost::shared_ptr?

struct A
{
    virtual ~A() {}
};

struct B : A
{
    B() {}
    virtual ~B() {}
};

void f(const std::shared_ptr<A>& ptr)
{}

BOOST_PYTHON_MODULE(test)
{
    class_<A, boost::noncopyable>("A", no_init);

    class_<B, std::shared_ptr<B>, bases<A>>("B")
        .def(init<>());

    def("f", f);
}

I am aware that the the boost::get_pointer method must be defined for std::shared_ptr, so I make sure that the following lines exist before a #include <boost/python.hpp>:

namespace boost {
template<class T> const T* get_pointer(const std::shared_ptr<T>& p)
{
    return p.get();
}

template<class T> T* get_pointer(std::shared_ptr<T>& p)
{
    return p.get();
}
} // namespace boost

Now, in python I try:

>>> from test import *
>>> b = B()
>>> f(b)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ArgumentError: Python argument types in
    test.f(B)
did not match C++ signature:
    f(std::shared_ptr<A>)

Note: The code above works fine for boost::shared_ptr, but I want to stick with the C++11 types instead.

Thanks.

A.L.
  • 1,133
  • 1
  • 12
  • 19
  • If anyone else stumbles upon this, @eudoxos has a working solution that below. You don't need to switch to `boost::shared_ptr`. – Michael Koval May 21 '15 at 15:41

2 Answers2

0

Boost.Python has special magic built in to recognize a boost::shared_ptr. It does not currently recognize a std::shared_ptr. For now, just frown and use boost::shared_ptr.

Matthew Scouten
  • 15,303
  • 9
  • 33
  • 50
0

I made once std::shared_ptr work with boost::python IIRC, using get_pointer as you write. (The relevant comment is here). My guess is that you need to have class_<A,std::shared_ptr<A>,...> since that is what your function takes as argument.

Community
  • 1
  • 1
eudoxos
  • 18,545
  • 10
  • 61
  • 110