我想创建 Herb Sutter describes here 的主动对象模式的现代(C++11 或 C++14)实现。 .此实现的一个特殊要求是它支持涉及安全所有权转移的消息,通过std::unique_ptr
,那些复制起来非常昂贵的对象。例如,应支持接近以下内容:
void sink(std::unique_ptr<int>) { /* ... */ }
Active active;
std::unique_ptr<int> unique(new int(0));
active.Send(std::bind(sink, unique));
以下基于 Herb 的实现无效。
#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();
}
}
};
使用此实现,上面的示例无法编译,错误表明无法从绑定(bind)类型转换为 std::function<void()>
.此错误源于 std::function
requires its argument to be CopyConstructible , 和 bind
ing unique_ptr
生成不可复制的绑定(bind)对象。
是否有替代方法来实现 Active
这样就避免了这个问题?
最佳答案
这是一个类型删除只移动包装器的粗略草图,它能够保存任何可以不带参数调用的可移动构造函数对象。
struct Message {
struct holder_base {
virtual void operator()() = 0;
virtual ~holder_base() = default;
};
template<class F>
struct holder : holder_base {
holder(F&& f) : func(std::move(f)) {}
void operator()() override { func(); }
F func;
};
Message() = default;
Message(Message&&) = default;
~Message() = default;
Message& operator=(Message&&) = default;
// copy members implicitly deleted
template<class F>
Message(F func) : p_func(new holder<F>(std::move(func))) {}
void operator()() const { (*p_func)(); }
std::unique_ptr<holder_base> p_func;
};
关于c++ - 在事件对象的实现中支持 unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29639519/