Search code examples
c++boostboost-python

Expose a non-const but noncopyable member in Boost Python


Here's my problem:

I have two classes like these:

class Signal {
public:
    void connect(...) { sig.connect(...); }
private:
    boost::signal2::signal sig;
};

class MyClass {
public:
    Signal on_event;
};

I would like to expose MyClass::on_event so that I can call my_class_instance.on_event.connect(...) from Python.

This is how I've wrapped those classes:

class_<Signal, boost::noncopyable> ("Signal", noinit)
    .def("connect", &some_helper_function);

class_<MyClass> ("MyClass")
    .def_readonly("on_event", &MyClass::on_event);

This compiles, but when I try to call connect from Python I get: AttributeError: can't set attribute. This is explained here: http://www.boost.org/doc/libs/1_53_0/libs/python/doc/tutorial/doc/html/python/exposing.html, so I changed to .def_readwrite for on_event.

But now I get a compile time error instead. Its an almost impossible to read C++ template error message, but as far as I understand it its because boost::signals2::signal is noncopyable. Since .def_readwrite makes the member assignable it must not be noncopyable. But for my usage I don't want to assign the member, I just wan't to call one method.

I thought about making the connect method of Signal const, even though it alters the object, but then I couldn't call sig.connect() from that method, so that was a no go as well..

Any ideas?


Solution

  • After writing this question I added a public copy constructor to Signal and now it works.