c++ - 在事件对象的实现中支持 unique_ptr

标签 c++ multithreading c++11 c++14

我想创建 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/

相关文章:

c++ - 正态分布发生器的种类

python - 多线程在同一程序中运行UDP客户端和UDP服务器

c++ - 线程安全和流管道

c++ - std::future.get() 多次调用(来自不同线程)

c++ - 要使用的默认 Visual Studio 项目设置 "rvalueCast"

c++ - 即使定义了用户定义的转换运算符,Static_cast 也拒绝将指针强制转换为类

c++ - Win32 API GetMessage()

c# - 嵌入式锁是否会针对竞争条件增加任何值(value)?

c++ - std::async 与类成员函数

c++ - 在 OpenCV 中将 float 转换为 unsigned char