对boost asio完成处理程序的rvalue引用

rvalue reference to boost asio completion handler

本文关键字:程序 rvalue 引用 处理 boost asio      更新时间:2023-10-16

在boost::asio中,是否可以在C++11中使用移动语义和右值引用模拟来创建和实现完成处理程序?

我的尝试如下,但我不明白我得到错误的原因:

类别定义:

struct SocketTest : std::enable_shared_from_this<SocketTest> {

  SocketTest(boost::asio::ip::udp::socket socket):socket_(std::move(socket)){}
  template<typename Handler>
  void async_receive(dummy dummy,Handler&& handler){
    auto self(shared_from_this());
    socket_.async_receive(boost::asio::buffer(buf_), 
       std::bind([this,self](
          boost::system::error_code ec, 
          std::size_t bytes_transferred, 
          Handler&& moved_handler
       ){
           moved_handler(ec,bytes_transferred);
        }, std::move(handler)));
  }
  std::array<char,max_length> buf_;
  boost::asio::ip::udp::socket socket_;
};

调用类的示例:

SocketTest socket_test(std::move(s));
socket_test.async_receive(dummy(), []( boost::system::error_code ec, std::size_t bytes_transferred){
    // many cool things accomplished!
});

似乎下面复制处理程序的版本工作正常,但我有兴趣学习如何避免这种复制:

struct SocketTest : std::enable_shared_from_this<SocketTest> {

  SocketTest(boost::asio::ip::udp::socket socket):socket_(std::move(socket)){}
  template<typename Handler>
  void async_receive(dummy dummy,Handler handler){
    auto self(shared_from_this());
    socket_.async_receive(boost::asio::buffer(buf_), [this,self,handler](boost::system::error_code ec, std::size_t bytes_transferred){
       handler(ec,bytes_transferred);
    });
  }
  std::array<char,max_length> buf_;
  boost::asio::ip::udp::socket socket_;
};

完整的来源和错误可以在这里找到

不能将bind引用到接受右值引用的可调用对象,因为当bind保存其参数时,它就不再是右值了。在您的情况下,您可以通过值让它接受Handler(这是存储处理程序的最后一个地方)。您可以查看此问题以了解更多详细信息。

此外,您忘记为bind:提供占位符

socket_.async_receive(boost::asio::buffer(buf_), 
   std::bind([this,self](
      boost::system::error_code ec, 
      std::size_t bytes_transferred, 
      Handler moved_handler
   // ^^^^^^^ passing by value 
   ){
       moved_handler(ec,bytes_transferred);
    }, std::placeholders::_1, std::placeholders::_2, std::move(handler)));
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ placeholders added