boost::python чистый виртуальный базовый класс со статическим конструктором фабрики и std::unique_ptr

Я просмотрел все связанные вопросы, которые смог найти, и не смог найти ответ на эту конкретную ситуацию.

У меня есть чистый виртуальный интерфейс базового класса С++, который я хочу предоставить Python. Реализация наследуется от Base и не раскрывается:

struct Base : private boost::noncopyable
{
    static std::unique_ptr<Base> create();
    virtual ~Base();
    virtual int get_int() = 0;
    virtual void set_int(const int i) = 0;
};

Мне не нужен Python для подкласса Base, только для того, чтобы иметь возможность создавать новые экземпляры Base с помощью функции фабрики create().

Я пробовал два подхода к обертыванию с помощью boost::python. Во-первых, аналогично Boost.Python: как выставить std::unique_ptr Я попытался создать функцию __init__, которая освобождает unique_ptr:

namespace bp = boost::python;
bp::class_<Base, boost::noncopyable>("Base", bp::no_init)
    .def("__init__",
         bp::make_function([](Base& self) { return Master::create().release(); },
         bp::return_value_policy<bp::manage_new_object>(),
         boost::mpl::vector<Base*, Base&>(), "Create a new Base")
    .staticmethod("__init__")

Это компилируется и загружается в Python, но __init__ на самом деле не статично!

create(...)
create( (Base)arg1) -> Base :
    Create a new Base

    C++ signature :
        Base* create(Base {lvalue})

Второй подход, который я пробовал, заключается в использовании make_constructor следующим образом:

namespace bp = boost::python;
bp::class_<Base, boost::noncopyable, std::unique_ptr<Base>>("Base", bp::no_init)
    .def("__init__", bp::make_constructor(&Base::create));
bp::register_ptr_to_python<std::unique_ptr<Master>>();

Однако это не компилируется: /usr/include/boost/python/make_constructor.hpp:40:20: fatal error: call to deleted constructor of std::unique_ptr<Base, std::default_delete<Base>> dispatch(x, is_pointer<T>());


person jondo2010    schedule 25.04.2016    source источник


Ответы (1)


Я смог заставить привязки работать, используя второй подход, переключившись с std::unique_ptr на std::shared_ptr, так как shared_ptr является конструктивным по умолчанию.

Это стало возможным, потому что я могу изменить исходный код библиотеки C++.

person jondo2010    schedule 25.04.2016