I'd like to create a modern (C++11 or C++14) implementation of the Active Object pattern that Herb Sutter describes here. A particular requirement of this implementation is that it support messages that involve safe transfer of ownership, via std::unique_ptr
, of objects that would be prohibitively expensive to copy. For example, something close to the following should be supported:
void sink(std::unique_ptr<int>) { /* ... */ }
Active active;
std::unique_ptr<int> unique(new int(0));
active.Send(std::bind(sink, unique));
The following implementation, based closely on Herb's, does not work.
#include <thread>
#include <queue>
// (Implementation of a threadsafe `message_queue` omitted.)
class Active {
public:
typedef std::function<void()> Message;
Active() : thd([&]{ Run(); }) {
}
~Active() {
Send([&]{ done = true; });
thd.join();
}
void Send(Message m) {
mq.send(m);
}
private:
bool done = false;
message_queue<Message> mq;
std::thread thd;
void Run() {
while (!done) {
Message msg = mq.receive();
msg();
}
}
};
With this implementation, the example above fails to compile, with errors indicating an inability to convert from the bind type to std::function<void()>
. This error stems from the fact that std::function
requires its argument to be CopyConstructible, and bind
ing a unique_ptr
produces a non-copyable bind object.
Is there an alternative way to implement Active
that avoids this issue?