Boost :: bind метод с параметром boost :: function - PullRequest
4 голосов
/ 28 января 2010

Я хотел бы предоставить дополнительную функцию boost :: async_write. Я хочу, чтобы сначала вызывалась собственная функция HandleWrite для соединений, а затем вызывался предоставленный boost :: function.

Метод Member элемента Connection, который связывается с asio async_write

void Connection::HandleWrite(
    const boost::system::error_code& e,
    boost::function<void (const boost::system::error_code&)> handler)
 {
    // Code removed for clarity

    if(!handler.empty())
        handler(e);
 };

Попытка привязать HandleWrite к asio async_write и предоставить другую привязку в качестве значения для обработчика. Это не компилируется. Что я делаю не так?

  void Connection::QueueRequest(
      boost::shared_array<char> message, 
      std::size_t size, 
      boost::function<void (const boost::system::error_code&)> handler)
  {
     // Code hidden for clarity

     boost::asio::async_write(m_Socket, boost::asio::buffer(buffer),
         boost::bind(&Connection::HandleWrite, shared_from_this(),
            boost::asio::placeholders::error,
            handler
         )
     );
  }

Сообщение об ошибке, полученное от компилятора, выглядит следующим образом:

Error 1   error C2825: 'F': must be a class or namespace when followed by '::'    boost\bind\bind.hpp 69
Error   2   error C2039: 'result_type' : is not a member of '`global namespace''    boost\bind\bind.hpp 69
Error   3   error C2146: syntax error : missing ';' before identifier 'type'    boost\bind\bind.hpp 69
Error   4   error C2208: 'boost::_bi::type' : no members defined using this type    boost\bind\bind.hpp 69
Error   5   fatal error C1903: unable to recover from previous error(s); stopping compilation   boost\bind\bind.hpp 69

Ответы [ 2 ]

0 голосов
/ 29 января 2010

Проблема оказалась в другом месте, которое использовало ту же функцию HandleWrite и не было правильно связано. После исправления это скомпилировано.

0 голосов
/ 28 января 2010

Какие ошибки вы получаете именно? Я не вижу ничего явно неправильного в коде, показанном в вашем вопросе, поэтому я не могу дать вам прямой ответ.

Однако ответ Корнеля заставил меня усомниться, так как я думал, что функторы, генерируемые boost :: bind, могут принимать любое количество аргументов и просто игнорировать дополнительные.

Так что я быстро взломал это, чтобы проверить:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <string>
#include <iostream>


void Foo(const boost::system::error_code&)
{
    // whatever
}

struct Client : boost::enable_shared_from_this<Client>
{
    void HandleWrite(
        const boost::system::error_code& Err, 
        boost::function<void(const boost::system::error_code&)> OtherHandler
    )
    {
        std::cout << "MyHandler(" << Err << ")\n";
        OtherHandler(Err);
    }

    void MakeTheCall(boost::function<void (const boost::system::error_code&)> Other)
    {
        using boost::asio::ip::tcp;

        // Of course, the scope and initialization of
        // io_service, sock and request are all wrong here,
        // as we're only interested in testing if the async_write
        // call below will compile.
        // Don't try to run this at home!
        boost::asio::io_service io_service;
        tcp::socket sock(io_service);
        boost::asio::streambuf request;

        boost::asio::async_write(sock, request,
            boost::bind(&Client::HandleWrite, shared_from_this(),
                boost::asio::placeholders::error,
                Other
            )
        );
    }
};


int main()
{
    boost::shared_ptr<Client> c;
    c->MakeTheCall(boost::bind(&Foo, _1));

    return 0;
}

что делает набросок того, что, я думаю, вы пытаетесь сделать.

Как и ожидалось, он компилируется, поэтому сравнение его с тем, что вы на самом деле делаете, может помочь вам найти проблему.

...