在 Active Object 的实现中支持 unique_ptr
Supporting unique_ptr in an implementation of Active Object
我想创建 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();
}
}
};
使用此实现,上面的示例无法编译,错误指示无法从绑定类型转换为 std::function<void()>
。此错误源于 std::function
requires its argument to be CopyConstructible,并且 bind
ing a unique_ptr
会生成不可复制的绑定对象。
是否有替代方法来实施 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;
};
我想创建 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();
}
}
};
使用此实现,上面的示例无法编译,错误指示无法从绑定类型转换为 std::function<void()>
。此错误源于 std::function
requires its argument to be CopyConstructible,并且 bind
ing a unique_ptr
会生成不可复制的绑定对象。
是否有替代方法来实施 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;
};