为什么我们可以在 acceptor_.async_accept 中重用移动的 socket_?
Why we can reuse a moved socket_ in acceptor_.async_accept?
参考: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_
。也就是说,原来由socket_(ioc)
初始化的listener::socket_
会变成未初始化的
问题> 如何将未初始化的 socket_
赋给 acceptor_.async_accept
?
谢谢
这完全取决于类型的实现。
我们可以粗略地将移动的意图描述为“允许编译器蚕食”。但实际上,对于 user-defined 类型 我们 将不得不确切地告诉它如何去做。
在语言“原则”中,一个 moved-from 对象只能被假定为可以安全销毁,但在实践中,许多库会做出更宽松的保证(例如,保留所有不变量,或确保 moved-from 对象相当于一个新建的对象)。
确实,ASIO documents 这个:
Remarks
Following the move, the moved-from object is in the same state as if constructed using the basic_stream_socket(const executor_type&) constructor.
参考: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_
。也就是说,原来由socket_(ioc)
初始化的listener::socket_
会变成未初始化的
问题> 如何将未初始化的 socket_
赋给 acceptor_.async_accept
?
谢谢
这完全取决于类型的实现。
我们可以粗略地将移动的意图描述为“允许编译器蚕食”。但实际上,对于 user-defined 类型 我们 将不得不确切地告诉它如何去做。
在语言“原则”中,一个 moved-from 对象只能被假定为可以安全销毁,但在实践中,许多库会做出更宽松的保证(例如,保留所有不变量,或确保 moved-from 对象相当于一个新建的对象)。
确实,ASIO documents 这个:
Remarks
Following the move, the moved-from object is in the same state as if constructed using the basic_stream_socket(const executor_type&) constructor.