【问题标题】:best way to move/copy string in async operation?在异步操作中移动/复制字符串的最佳方法?
【发布时间】:2020-05-04 19:46:43
【问题描述】:

考虑以下示例,为异步操作移动/复制/捕获字符串的最佳方法是什么?在 Session 中传递 & 是个好主意吗?

void Client::connect(const std::string& hostname, const std::string& port, const std::string& string) {
  auto socket_ = std::make_shared<net::ip::tcp::socket>(_io_context);
  net::ip::tcp::resolver resolver_(_io_context);
  auto endpoints_ = resolver_.resolve(hostname, port);

  net::async_connect(*socket_, endpoints_, [socket_, string](sys::error_code ec, net::ip::tcp::endpoint) {
    if(!ec) {
      std::make_shared<Session>(std::move(*socket_), std::move(string))->start();
    }
  });
}

Session::Session(net::ip::tcp::socket socket, const std::string& string)
  : _socket(std::move(socket)), _string(std::move(string)) {

}

【问题讨论】:

    标签: c++ string boost-asio move-semantics


    【解决方案1】:

    仅按值传递字符串并移动它既干净又高效。

    void Client::connect(const std::string& hostname, const std::string& port, std::string string) {
      auto socket_ = std::make_shared<net::ip::tcp::socket>(_io_context);
      net::ip::tcp::resolver resolver_(_io_context);
      auto endpoints_ = resolver_.resolve(hostname, port);
    
      net::async_connect(*socket_, endpoints_, [socket_, string{std::move(string)}](sys::error_code ec, net::ip::tcp::endpoint) mutable {
        if(!ec) {
          std::make_shared<Session>(std::move(*socket_), std::move(string))->start();
        }
      });
    }
    
    Session::Session(net::ip::tcp::socket socket, std::string string)
      : _socket(std::move(socket)), _string(std::move(string)) {
    
    }
    

    请特别注意 lambda 捕获中允许将对象移动到 lambda 中的语法。

    【讨论】:

    • 所以假设是正确的,如果我将它作为 & 在会话构造函数中添加添加工作,那么在运行时会有从字符串到 & 然后取消引用的添加转换?假设 _string 成员也是 const std::string _string?
    • @newbie,不,这对任何实质性的影响都没有。改变的是,通过接受const std::string&amp;,您必须有两个字符串对象,一个是您从中读取的只读源对象,一个是您复制到的目标_string 对象。通过按值获取字符串,并从源移动到目标,您可以避免创建字符串数据的副本。
    • 如果我不使用字符串作为成员,而是使用它来初始化不同的成员,例如:_file(std::move(string), std::ifstream::in | std::fstream ::binary), file_size(std::filesystem::file_size(std::move(string)))
    • @newbie,在这种情况下,是的,如果没有任何东西获得字符串的所有权,那么您应该通过常量引用来接受它(并且在调用 Session 的构造函数时也不要移动它)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2010-09-16
    • 2017-12-20
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多