2

参考:https://www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/reference/basic_socket_acceptor/async_accept/overload1.html

boost::asio::ip::tcp::acceptor acceptor(io_service);
...
boost::asio::ip::tcp::socket socket(io_service); 
// you have to initialize socket with io_service first before 
//you can use it as a parameter on async_accept.
acceptor.async_accept(socket, accept_handler);

参考:

https://github.com/vinniefalco/CppCon2018/blob/master/listener.cpp

listener::  listener(
    net::io_context & ioc,
    tcp::endpoint endpoint,
    std::shared_ptr < shared_state >
    const & state): acceptor_(ioc), socket_(ioc), state_(state) {

// Accepts incoming connections and launches the sessions
class listener : public std::enable_shared_from_this<listener>
{
    tcp::acceptor acceptor_;
    tcp::socket socket_;
...
}

// Handle a connection
void listener::  on_accept(error_code ec) {
    if (ec)
      return fail(ec, "accept");
    else
      // Launch a new session for this connection
      std::make_shared < http_session > (
        std::move(socket_),                    // socket_ is moved here?
        state_) -> run();

    // Accept another connection
    acceptor_.async_accept(
      socket_,                                 // why we still can use it here?
      [self = shared_from_this()](error_code ec) {
        self -> on_accept(ec);
      });
  }

根据我的理解,std::move(socket_)允许编译器蚕食socket_. 换句话说,listener::socket_最初初始化的 bysocket_(ioc)将变为未初始化的。

问题>我们怎样才能给一个未初始化socket_ 的to acceptor_.async_accept

谢谢

4

1 回答 1

2

这完全取决于类型的实现。

我们可以将移动的意图大致描述为“允许编译器蚕食”。但实际上,对于用户定义的类型,我们将不得不准确地告诉它如何做到这一点。

在语言“学说”中,只能假设移出对象可以安全销毁,但实际上许多库会做出更宽松的保证(例如,保留所有不变量,或确保移出对象与新构造的对象具有可比性)。

事实上,ASIO记录了这一点:

评论

移动之后,被移动的对象处于与使用 basic_stream_socket(const executor_type&) 构造函数构造时相同的状态。

于 2022-02-18T02:33:33.830 回答