在boost :: asio中,是否可以在C ++ 11中使用移动语义和rvalue引用模拟来创建和实现完成处理程序?
我的尝试如下,但我不明白我得到错误的原因:
班级定义:
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_;
};
答案 0 :(得分:1)
你不能bind
到一个可调用对象进行右值引用,因为当bind
保存其参数时,它不再是右值。在您的情况下,您可以通过值接受Handler
(这是存储处理程序的最终位置)。您可以查看this question了解更多详情。
此外,您忘记为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