Boost.Python возвращает список не копируемых объектов

У меня есть тип X который не может быть скопирован, и я хочу показать функцию, которая создает list из них:

#include <boost/python.hpp>

namespace py = boost::python;

struct X {
    X(int i) : i(i) { }
    X(const X& ) = delete;
    X& operator=(X const&) = delete;

    int i;
    friend std::ostream& operator<<(std::ostream& os, X const& x) {
        return os << "X(" << x.i << ")";
    }
};

py::list get_xs(int n) {
    py::list xs;
    for (int i = 0; i < n; ++i) {
        xs.append(X{i});
    }
    return xs;
}

BOOST_PYTHON_MODULE(Foo)
{
    py::class_<X, boost::noncopyable>("X", py::init<int>())
        .def(str(py::self))
        .def(repr(py::self))
    ;

    py::def("get_xs", get_xs);
}

Это прекрасно компилируется, но когда я пытаюсь его использовать, у меня возникает ужас:

>>> import Foo
>>> Foo.get_xs(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: X

Что на самом деле означает эта ошибка? Как мне это исправить?

1 ответ

Решение

noncopyable похоже, проблема. когда X копируемо тогда все нормально.

Если X должно быть noncopyable затем boost::shared_ptr может быть использован:

py::list get_xs(int n) {
    py::list xs;
    for (int i = 0; i < n; ++i) {
        xs.append(boost::shared_ptr<X>(new X(i)));
    }
    return xs;
}

....

BOOST_PYTHON_MODULE(Foo)
{
    py::class_<X, boost::shared_ptr<X>, boost::noncopyable>("X", py::init<int>())
    ...
    ...

    py::register_ptr_to_python<boost::shared_ptr<X>>();
}
Другие вопросы по тегам