Boost Tuple вызывает проблемы с функцией Boost Bind / Boost? - PullRequest
1 голос
/ 21 января 2012

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

Я делаю кое-что boost :: asio и пытаюсь написать шаблонныйфункция асинхронного чтения.

Вот функция.

template <typename Handler>
void AsyncRead(std::vector<boost::uint8_t>& _inMsg, Handler _handler)
{
    #if debug
      std::cout<< "IConnection::AsyncRead" << std::endl;
    #endif
    using namespace protocols;

    typedef boost::tuple<Handler> tHandler;
    typedef boost::function< void(const boost::system::error_code &, std::vector<boost::uint8_t> &, tHandler ) > HeaderReaderFunc;

    //void (AConnection::*f)(const boost::system::error_code&, std::vector<boost::uint8_t>&, boost::tuple<Handler>) = &AConnection::HandleReadHeader<Handler>;


    tHandler t(boost::make_tuple(_handler));
    HeaderReaderFunc x(boost::bind(&AConnection::HandleReadHeader<Handler>, this, boost::asio::placeholders::error, boost::ref(_inMsg), t));
    inboundHeader.resize(sizeof(SocketIO::MsgData));
    boost::asio::async_read(socket, boost::asio::buffer(inboundHeader), x);

}

В последнем выражении этой функции дела идут плохо.

boost::asio::async_read(socket, boost::asio::buffer(inboundHeader), x);

Когда я пытаюсь пройтипеременная 'x' в качестве параметра функции async_read.

Ошибки легендарны как по длине, так и без расшифровки.

Просто небольшой пример вывода ошибок:

boost_1_38_0/boost/asio/detail/bind_handler.hpp: In member function ‘void boost::asio::detail::binder2<Handler, Arg1, Arg2>::operator()() [with Handler =  boost::function<void ()(const boost::system::error_code&, std::vector<unsigned char, std::allocator<unsigned char> >&, boost::tuples::tuple<boost::function<void ()(const boost::system::error_code&)>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>)>, Arg1 = boost::system::error_code, Arg2 = unsigned int]’:

Если я не использую здесь функцию повышения, а вместо этого использую закомментированную строку, которая является ссылкой на функцию-член, вещи вроде бы работают, но я не могу понять, почему это так.

Подпись функции для шаблона функции AConnection :: HandleReadHeader:

template <typename Handler>
void HandleReadHeader(const boost::system::error_code& _e,
                    std::vector<boost::uint8_t> & _inMsg, 
                    boost::tuple<Handler> _handler)

Тип обработчика:

    boost::function<void (const boost::system::error_code & ) >

Функции AsyncRead и HandleReadHeader являются членами моего собственногокласс AConnection(вероятно, не важно).

Либо я что-то упускаю из-за синтаксиса в отношении создания объекта boost :: function, подпись которого включает boost :: tuple, либо функции boost :: asio :: async_readТретий тип параметра не соответствует моей переменной 'x'.

Любая помощь приветствуется.Спасибо.

РЕДАКТИРОВАТЬ:

Вот код, который работает, но использует ссылку на функцию-член вместо boost :: functon.

template <typename Handler>
void AsyncRead(std::vector<boost::uint8_t>& _inMsg, Handler _handler)
{
 #if debug
   std::cout<< "Connection::AsyncRead" << std::endl;
 #endif
 using namespace protocols;
 // Issue a read operation to read exactly the number of bytes in a header.
 void (Connection::*f)(
     const boost::system::error_code&,
     std::vector<boost::uint8_t>&, boost::tuple<Handler>)
   = &Connection::HandleReadHeader<Handler>;

 inboundHeader.resize(sizeof(simple::message_header));
 boost::asio::async_read(socket, boost::asio::buffer(inboundHeader),
     boost::bind(f,
     this, boost::asio::placeholders::error, boost::ref(_inMsg),
     boost::make_tuple(_handler)));
}

1 Ответ

0 голосов
/ 21 января 2012

Ваша переменная x имеет такой тип:

boost::function< void(const boost::system::error_code &,
    std::vector<boost::uint8_t> &, boost::tuple<Handler>) >

Что похоже на эту подпись:

void handler(const boost::system::error_code &,
    std::vector<boost::uint8_t> &, boost::tuple<Handler>)

Тем не менее, документы Boost Asio говорят, что подпись обработчика должна быть такой:

void handler(const boost::system::error_code&,
    std::size_t bytes_transferred)

Итак, ваши подписи не совпадают - даже не близки.Либо вы используете некоторую перегрузку, которую я не смог найти в документах Boost, либо вам нужно изменить тип HeaderReaderFunc, чтобы он соответствовал тому, что ожидает async_read.

...