Использование Boost Python & std:: shared_ptr - программирование
Подтвердить что ты не робот

Использование Boost Python & std:: shared_ptr

Я пытаюсь заставить Boost Python хорошо играть с std:: shared_ptr. В настоящее время я получаю эту ошибку:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    comp.place_annotation(circle.centre())
TypeError: No to_python (by-value) converter found for C++ type: std::shared_ptr<cgl::Anchor>

От вызова circle.centre(), который возвращает std:: shared_ptr. Я мог бы изменить каждый std:: shared_ptr на boost:: shared_ptr (с которым хорошо работает Boost Python), однако количество кода, которое нужно изменить, довольно значительное, и я бы хотел использовать стандартную библиотеку.

Метод круга объявляется следующим образом:

const std::shared_ptr<Anchor> centre() const
{
    return Centre;
}

Якорный класс выглядит следующим образом:

class Anchor
{
    Point Where;
    Annotation* Parent;
public:

    Anchor(Annotation* parent) :
        Parent(parent)
    {
        // Do nothing.
    }

    void update(const Renderer& renderer)
    {
        if(Parent)
        {
            Parent->update(renderer);
        }
    }

    void set(Point point)
    {
        Where = point;
    }

    Point where() const
    {
        return Where;
    }
};

И соответствующий код Boost Python:

class_<Circle, bases<Annotation> >("Circle", init<float>())
.def("radius", &Circle::radius)
    .def("set_radius",  &Circle::set_radius)
    .def("diameter", &Circle::diameter)
    .def("top_left", &Circle::top_left)
    .def("centre", &Circle::centre);

// The anchor base class.
class_<Anchor, boost::noncopyable>("Anchor", no_init)
    .def("where", &Anchor::where);

Я использую Boost 1.48.0. Любые идеи?

4b9b3361

Ответ 1

Похоже на boost:: python не поддерживает С++ 11 std:: shared_ptr.

Если вы посмотрите на файл boost/python/converter/shared_ptr_to_python.hpp, вы найдете реализацию функции шаблона shared_ptr_to_python (shared_ptr <T> const & x) для boost:: shared_ptr (он объясняет, почему код работает нормально для boost:: shared_ptr).

Я думаю, у вас есть несколько вариантов:

  • использовать boost:: shared_ptr (которого вы пытаетесь избежать)
  • напишите свою реализацию shared_ptr_to_python для std:: shared_ptr (IMHO лучший вариант)
  • отправить запрос на boost:: разработчики python для поддержки std:: shared_ptr

Ответ 4

Отрывок из http://boost.2283326.n4.nabble.com/No-automatic-upcasting-with-std-shared-ptr-in-function-calls-td4573165.html:

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

Работал для меня. Вы бы определили ваши классы следующим образом:

class_<foo, std::shared_ptr<foo>>("Foo", ...);

При этом другие методы, возвращающие std::shared_ptr<foo>, будут просто работать.

Для виртуальных функций/полиморфизма может потребоваться некоторая магия, которая должна быть покрыта в потоке, к которому я привязан.