为什么这个boost::asio::tcp::socket可以重复使用?
Why can this boost::asio::tcp::socket be re-used?
下面是一些代码 from a boost::asio example。为什么在构造 chat_session
时可以移动 socket_
成员,如果处理程序底部的递归调用将在下次接受发生时传递相同的 tcp::socket
?我以为移动操作后,一个对象不再安全使用。
class chat_server
{
public:
chat_server(boost::asio::io_service& io_service,
const tcp::endpoint& endpoint)
: acceptor_(io_service, endpoint),
socket_(io_service)
{
do_accept();
}
private:
void do_accept()
{
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec)
{
if (!ec)
{
std::make_shared<chat_session>(std::move(socket_), room_)->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
chat_room room_;
};
你是对的,移动后套接字对象不可用。
但是 调用您的 lambda 的代码将创建一个 new 套接字并初始化您的变量socket_
使用那个新插座。因此,下次调用 lambda 时,它实际上是一个 不同的 套接字。
该代码等效于执行以下操作:
some_class o;
while ( true )
{
// assign a new instance of some_class to the o variable, calling o.bar() is valid
o = some_class(...);
foo(std::move(o));
// o is no longer valid calling o.bar() would fail
}
对async_accept
的调用将套接字重新初始化为可以使用的有效值。移动的对象处于未指定(但有效)状态,由该对象的实现者决定该状态是什么。在 asio::tcp::socket
的情况下,状态是一个未初始化的套接字,可用于新连接。
标准规定 "moved-from" 对象必须至少处于有效的未指定状态。
移出的套接字可以安全使用,因为它的状态在文档中明确指定:
下面是一些代码 from a boost::asio example。为什么在构造 chat_session
时可以移动 socket_
成员,如果处理程序底部的递归调用将在下次接受发生时传递相同的 tcp::socket
?我以为移动操作后,一个对象不再安全使用。
class chat_server
{
public:
chat_server(boost::asio::io_service& io_service,
const tcp::endpoint& endpoint)
: acceptor_(io_service, endpoint),
socket_(io_service)
{
do_accept();
}
private:
void do_accept()
{
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec)
{
if (!ec)
{
std::make_shared<chat_session>(std::move(socket_), room_)->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
chat_room room_;
};
你是对的,移动后套接字对象不可用。
但是 调用您的 lambda 的代码将创建一个 new 套接字并初始化您的变量socket_
使用那个新插座。因此,下次调用 lambda 时,它实际上是一个 不同的 套接字。
该代码等效于执行以下操作:
some_class o;
while ( true )
{
// assign a new instance of some_class to the o variable, calling o.bar() is valid
o = some_class(...);
foo(std::move(o));
// o is no longer valid calling o.bar() would fail
}
对async_accept
的调用将套接字重新初始化为可以使用的有效值。移动的对象处于未指定(但有效)状态,由该对象的实现者决定该状态是什么。在 asio::tcp::socket
的情况下,状态是一个未初始化的套接字,可用于新连接。
标准规定 "moved-from" 对象必须至少处于有效的未指定状态。
移出的套接字可以安全使用,因为它的状态在文档中明确指定: