boost::beast::bind_front_handler 是如何工作的?

for*_*Dev 9 c++ boost boost-beast

我正在尝试boost::beast示例,我遇到了这段代码。

    void on_write(beast::error_code ec, std::size_t byte_transferred) {
        if (ec) return fail(ec, "write");

        http::async_read(m_tcp_stream, m_buffer, m_response, beast::bind_front_handler(
            &Session::on_read, shared_from_this()));
    }

    void on_read(beast::error_code ec, std::size_t bytes_transferred) {
        if (ec) return fail(ec, "read");
        //std::cout << m_response << std::endl;
        write_on_file(m_response);
        m_tcp_stream.socket().shutdown(tcp::socket::shutdown_both, ec);
        if (ec && ec != beast::errc::not_connected) return fail(ec, "showdown");
    }
Run Code Online (Sandbox Code Playgroud)

特别是http::async_read(m_tcp_stream, m_buffer, m_response, beast::bind_front_handler(&Session::on_read, shared_from_this()));这一行。我无法理解它的代码。它是如何工作的。据我从代码中得到的信息,它返回它在其内部bind_front_wrapper构造了 a 。但我不明白它如何设法获取传入的参数,即使我们没有传递,我们只是传递。在本例中是调用方法。但我们没有传递任何参数,但它仍然被调用,我想知道如何?Handlertuple of argsHandlerbind_front_handlershared_ptrasync_readon_read

raf*_*x07 4

您使用异步操作,因此您的工作是定义操作完成时由 Beast 核心代码调用的回调。当由 启动的操作async_read准备就绪时,将async_read使用两个参数调用传递给的处理程序:错误代码 + 传输的字节数。您决定on_read通过 包装到回调中bind_front_handlerbind_front_handler生成一个仿函数对象,其伪代码实现可能如下所示:

class Handler {
    void (Session::*onRead)(...); // pointer to on_read function member of Session
    Session* session;  // pointer to session, get by shared_from_this

    Handler(/* pointer to on_read, pointer to session */) {}

    template<class ... Args>
    void operator() (Args... args) {
        ((*session).*onRead)(args...);
    }        
}
Run Code Online (Sandbox Code Playgroud)

当读取操作准备就绪时,operator()将使用两个参数包调用上述处理程序的函数:错误代码和读取字节数。

由于 c++20 已经有了std::bind_front,您可以访问参考以获取如何在 Beast 库中实现它的更多详细信息。

  • [tag:boost] 可能是一个相当吃力不讨好的坑:) 感谢您写出这样精彩的答案 (4认同)