简体   繁体   中英

boost::python pure virtual base class with static factory constructor and std::unique_ptr

I've looked at all the related questions I could find, and couldn't come up with an answer to this specific situation.

I have a C++ pure virtual base class interface that I want to expose to Python. The implementation inherits from Base and is not exposed:

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;
};

I don't need Python to subclass Base, only to be able to construct new Base instances through the create() factory function.

I've tried two approaches to wrapping with boost::python. First, similar to Boost.Python: How to expose std::unique_ptr I tried to create an __init__ function that releases the 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__")

This compiles and loads in Python, but __init__ is not actually static!

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

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

The 2nd approach I tried is to use make_constructor as follows:

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>>();

However this doesn't compile: /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>());

I was able to make the bindings work using the 2nd approach by switching from std::unique_ptr to std::shared_ptr since shared_ptr is default constructible.

This was possible because I'm able to modify the C++ library source.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM