【问题标题】:Can't use asio::placeholders::error in non-Boost version of Asio不能在非 Boost 版本的 Asio 中使用 asio::placeholders::error
【发布时间】:2015-02-12 19:40:32
【问题描述】:

我正在尝试在项目中使用非 Boost 版本的 Asio。我正在给stream_protocol::acceptor::async_accept 写一个回调。签名需要传递asio::placeholders::error,但是当我这样做时,我收到以下错误:

error: no member named 'error' in namespace 'asio::placeholders'

按照源代码,我可以看到错误存在但类型为undefined,这对我来说是新的。我错过了什么吗?我应该对库进行某种预处理吗?

【问题讨论】:

    标签: c++ c++11 boost boost-asio


    【解决方案1】:

    简而言之,使用std::placeholders::_1 而不是asio::placeholders:error


    Asio 仅在使用 Boost.Bind 时支持方便的占位符变量。 error 占位符 documentation 表示:

    一个参数占位符,用于 boost::bind(), ...

    使用std::bind() 创建处理程序时,需要使用std::bind 的占位符。 async_accept() 操作接受满足 AcceptHandler 类型要求的处理程序:

    接受处理程序必须满足处理程序的要求。接受处理程序类的值h 应该在表达式h(ec) 中正常工作,其中ecconst error_code 类型的左值。

    当使用std::bind() 创建一个函子以充当AcceptHandler 时,如果希望获得error_code 参数,则使用std::placeholders::_1

    void handle_accept(const std::error_code&);
    
    acceptor.async_accept(server_socket, std::bind(&handle_accept,
      std::placeholders::_1 /* error_code */));
    

    这是一个使用std::bind() 的完整最小示例demonstrating。请注意,coliru 似乎没有可用的 Asio 独立版本,但示例应该足够了:

    #include <iostream>
    #include <functional>
    
    #include <boost/asio.hpp>
    
    void handle_accept(const boost::system::error_code& error_code)
    {
      std::cout << "handle_accept: " << error_code.message() << std::endl;
    }
    
    void noop() {}
    
    int main()
    {
      using boost::asio::ip::tcp;
      boost::asio::io_service io_service;
    
      // Create all I/O objects.
      tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
      tcp::socket server_socket(io_service);
      tcp::socket client_socket(io_service);
    
      // Connect client and server sockets.
      acceptor.async_accept(server_socket, std::bind(&handle_accept,
        std::placeholders::_1 /* error_code */));
      client_socket.async_connect(acceptor.local_endpoint(), std::bind(&noop));
      io_service.run();
    }
    

    输出:

    handle_accept: Success
    

    如果希望更详细一点,可以选择使用命名占位符:

    namespace asio_placeholders
    {
      auto error = std::placeholders::_1;
    }
    
    // ...
    
    acceptor.async_accept(server_socket, std::bind(&handle_accept,
      asio_placeholders::error));
    

    源码中观察到的unspecified类型只在生成文档时使用,如code所示:

    #if defined(GENERATING_DOCUMENTATION)
    
    /// An argument placeholder, for use with boost::bind(), that corresponds to
    /// the error argument of a handler for any of the asynchronous functions.
    unspecified error;
    
    // ...
    
    #elseif
    

    【讨论】:

    • 或者,当使用 Boost.Bind 和非增强 Asio 时,您必须定义 ASIO_HAS_BOOST_BIND 以获得便利的占位符。
    猜你喜欢
    • 2011-02-12
    • 2017-09-02
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多