使用boost::bind绑定了错误的模板类方法

binding the wrong template class method using boost::bind

本文关键字:错误 类方法 boost bind 绑定 使用      更新时间:2023-10-16

有一个基类asio_handler:

class T>是定义boost::asio套接字的类型(纯文本,或封装的ssl)

template <class T> asio_handler:
{
    // ...
    asio_handler(const std::shared_ptr<T> sock)
    : socket_(sock)
    {}
    // this method handles connections
    void do_connect(const boost::system::error_code & err)
    {
        boost::asio::async_read_until(*socket_,
                                      http_response::buffer_,
                                      rn_,
                                      boost::bind(&asio_handler<T>::read_status_line, 
                                                  this, 
                                                  boost::asio::placeholders::error));
    }
    void read_status_line(const boost::system::error_code & err)
    {
         // same as before, binding to an asio_handler<T>::method
    }
private:
    const std::shared_ptr<T> socket_;
};
其中一个继承类是asio_http,它使用http_socket:
typedef boost::asio::ip::tcp::socket http_socket;
class asio_http : public asio_handler<http_socket>
{
    // ... construct appropriately
    void connect(const boost::system::error_code err)
    {
        boost::asio::async_write(*socket_,
                                     request_,
                                     boost::bind(&asio_handler<http_socket>::do_request<http_socket>, 
                                                 this,
                                                 boost::asio::placeholders::error));
    }
};

问题似乎是模板类方法被绑定是未知的?(除非我理解错了,这并不奇怪)。

/usr/local/include/boost/bind/bind.hpp:69:22: error: type 'void (rapp::cloud::asio_handler<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >::*)(const
      boost::system::error_code &)' cannot be used prior to '::' because it has no members
    typedef typename F::result_type type;
                     ^

这似乎与:

/usr/local/include/boost/bind/bind_template.hpp:15:22: note: in instantiation of template class 'boost::_bi::result_traits<boost::_bi::unspecified, void (rapp::cloud::asio_handler<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
      boost::asio::stream_socket_service<boost::asio::ip::tcp> > >::*)(const boost::system::error_code &)>' requested here
    typedef typename result_traits<R, F>::type result_type;

从继承类绑定的所有回调向基类回调传播。

我在上面发布的这个极其神秘的错误是由:

Apple LLVM version 7.0.2 (clang-700.1.81)

尝试在Ubuntu/GCC下编译相同的代码会产生一个更有用的错误:

/usr/include/boost/bind/bind.hpp: In instantiation of ‘struct boost::_bi::result_traits<boost::_bi::unspecified, void (rapp::cloud::asio_handler<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >::*)(const boost::system::error_code&)>’:

我搜索了一下,发现了这篇博客文章,它解释了这个错误只是方法签名与占位符不匹配。

确实是这样,解决方案很简单:

void read_content(
                  const boost::system::error_code & err,
                  const std::size_t bytes
                 );

我真的希望这能帮助像我一样被困在这个问题上的人,这个错误很愚蠢,但是产生的错误信息很难破译。

最终这是我的错误,因为boost::asio::async_read函数在参数上是明确的。