Экспорт классов, не поддающихся конструированию по умолчанию, с помощью Boost.Python

#c #boost-python

#c #boost-python

Вопрос:

Как мне экспортировать класс, не поддающийся конструированию по умолчанию, с помощью Boost.Python?

Этот код:

 class EventHandle {
 public:
  EventHandle() = delete;
  EventHandle(boost::shared_ptr<EventManager> constamp; em): event_manager_(em) {}
  EventHandle(EventHandle constamp;) = delete;
  ~EventHandle();
  shared_ptr<EventManager> event_manager_;
}
class_<EventHandle, noncopyable,
  init<boost::shared_ptr<EventManager> constamp;>>("EventHandle")
  

выдает следующую ошибку:

 /opt/local/include/boost/python/pointee.hpp: In instantiation of 'boost::python::detail::pointee_impl<false>::apply<boost::python::init<const boost::shared_ptr<EventManager>amp;> >':
/opt/local/include/boost/python/pointee.hpp:38:1:   instantiated from 'boost::python::pointee<boost::python::init<const boost::shared_ptr<EventManager>amp;> >'
/opt/local/include/boost/mpl/eval_if.hpp:38:31:   instantiated from 'boost::mpl::eval_if<boost::is_convertible<boost::python::init<const boost::shared_ptr<EventManager>amp;>*, EventHandle*>, boost::mpl::identity<boost::python::init<const boost::shared_ptr<EventManager>amp;> >, boost::python::pointee<boost::python::init<const boost::shared_ptr<EventManager>amp;> > >'
/opt/local/include/boost/python/object/class_metadata.hpp:179:13:   instantiated from 'boost::python::objects::class_metadata<EventHandle, boost::noncopyable_::noncopyable, boost::python::init<const boost::shared_ptr<EventManager>amp;>, boost::python::detail::not_specified>'
/opt/local/include/boost/python/class.hpp:174:42:   instantiated from 'boost::python::class_<EventHandle, boost::noncopyable_::noncopyable, boost::python::init<const boost::shared_ptr<EventManager>amp;> >::id_vector'
/opt/local/include/boost/python/class.hpp:627:55:   instantiated from 'boost::python::class_<T, X1, X2, X3>::class_(const char*, const char*) [with W = EventHandle, X1 = boost::noncopyable_::noncopyable, X2 = boost::python::init<const boost::shared_ptr<EventManager>amp;>, X3 = boost::python::detail::not_specified]'
/Users/neil/nn/src/core/python_event.cc:21:66:   instantiated from here
/opt/local/include/boost/python/pointee.hpp:28:44: error: no type named 'element_type' in 'class boost::python::init<const boost::shared_ptr<EventManager>amp;>'
make[3]: *** [CMakeFiles/distributions.dir/core/python_event.cc.o] Error 1
make[2]: *** [CMakeFiles/distributions.dir/all] Error 2
make[1]: *** [CMakeFiles/distributions.dir/rule] Error 2
make: *** [distributions] Error 2
  

Ответ №1:

Вам нужно предоставить конструктор с помощью init<...> . Например, для конструктора, принимающего два целых числа:

 class_<MyClass>("MyClass", init<int, int>())
    ....
  

Обратите внимание, что вам нужно поместить init внутри class_ параметров, а не в отдельном .def() вызове, иначе Boost предположит, что у вас есть конструктор по умолчанию.

Смотрите раздел руководства о конструкторах.

Редактировать: Для вашего кода попробуйте:

 class_<EventHandle, noncopyable>("EventHandle", 
    init<boost::shared_ptr<EventManager> constamp;>())
  

Комментарии:

1. @Neil: Поместите init в class_ параметры, как в моем примере, а не в отдельный .def . В противном случае Boost будет считать, что у вас есть конструктор по умолчанию.

2. Большое спасибо! По-прежнему не работает (см. Обновленный вопрос), но становится намного ближе.

3. @Neil: Попробуйте использовать точно такой же тип в init , что и в конструкторе, т.е. shared_ptr<EventManager> constamp; .

Ответ №2:

Вы пробовали использовать no_ini t? В документах говорится, что это для случаев, когда вам не нужны конструкторы, но, возможно, вы можете объединить это с явным запросом одного?

 class_<EventHandle, noncopyable,
    init<boost::shared_ptr<EventManager> constamp;> >
    ("EventHandle", no_init)