Должен ли std::bind быть совместимым с boost::asio?

Я пытаюсь адаптировать один из примеров boost::asio для использования библиотек С++ 11/TR1, где это возможно. Исходный код выглядит так:

void start_accept()
{ 
  tcp_connection::pointer new_connection =
    tcp_connection::create(acceptor_.get_io_service());

  acceptor_.async_accept(new_connection->socket(),
      boost::bind(&tcp_server::handle_accept, this, new_connection,
         boost::asio::placeholders::error));
}

Если я заменю boost::bind на std::bind следующим образом:

void start_accept()
{ 
  tcp_connection::pointer new_connection =
    tcp_connection::create(acceptor_.get_io_service());

  acceptor_.async_accept(new_connection->socket(),
      std::bind(&tcp_server::handle_accept, this, new_connection,
                 boost::asio::placeholders::error ) );
      // std::bind(&tcp_server::handle_accept, this, new_connection, _1 ) );
}

Я получаю большое сообщение об ошибке, заканчивающееся на:

/usr/include/c++/4.4/tr1_impl/functional:1137: error: return-statement with a value, in function returning 'void'

Я использую gcc версии 4.4 с версией boost 1.47.

Я ожидал, что boost::bind и std::bind будут взаимозаменяемыми.


person mark    schedule 19.01.2012    source источник
comment
std многое берет от boost и tr1, но это не одно и то же. Интересно, имеет ли это какое-то отношение к этому вопросу   -  person spraff    schedule 19.01.2012
comment
потенциально связанный билет   -  person Sam Miller    schedule 19.01.2012
comment
@Sam Miller Я нашел билет, но он не обновлялся 3 года! Я также пробовал это против v1.48 boost и использовал std::placeholders вместо boost::asio::placeholders. На данный момент я придерживаюсь boost::shared_ptr и boost::bind для кода asio.   -  person mark    schedule 20.01.2012
comment
Помню когда-то у меня была похожая проблема. Вы пытались заменить boost::asio::placeholders::error на std::placeholders::_1 (или, может быть, _2)   -  person Richard    schedule 20.01.2012
comment
Если у вас есть std::bind, я предполагаю, что у вас есть лямбда-выражения, и в этом случае вы можете сделать что-то вроде: [=](const boost::system::error_code& error){ /*do code here or...*/ this->handle_accept(...)}. Лично я вообще перестал использовать привязку и просто пишу ее как лямбда, независимо от того, вызывает ли лямбда функцию или делает что-то встроенное. Моя мысль такова: зачем использовать библиотечную функцию, когда есть языковая функция, которая делает то же самое? Я знаю, что это был не твой вопрос, просто мои 0,02 доллара.   -  person David    schedule 27.01.2012
comment
@Dave - просто личное предпочтение - я предпочитаю использовать привязку при вызове существующего объекта функции-члена и использовать лямбда-выражения, когда существующие функции еще недоступны. В этом случае привязка зафиксирует это, и (насколько мне известно) конечный результат будет таким же. Кстати, библиотека boost::phoenix очень удобна для создания лямбда-выражений, она идет намного дальше лямбда-выражений C++11 (она поддерживает полиморфные лямбда-выражения).   -  person mark    schedule 27.01.2012
comment
Я думаю, этот вопрос должен быть закрыт сейчас?   -  person Denis Washington    schedule 01.03.2012
comment
@denisw Я бы закрыл его, но нет подходящей причины, когда я нажимаю закрыть, варианты не по теме, дублируются, не являются вопросом, слишком локализованы или неконструктивны. Что ты предлагаешь?   -  person mark    schedule 01.03.2012
comment
@mark Поместите свое решение в ответ, а затем примите его. Это также означает, что любой, кто ищет ответ на подобную проблему, не просто пропустит вопрос, потому что он закрыт, без ответа.   -  person dlanod    schedule 02.03.2012


Ответы (1)


Теперь у меня есть решение

Проблема в том, что когда я впервые попытался переключиться на std::bind и std::shared_ptr Я все еще использовал boost::asio::placeholders с std::bind, это привело к большому количеству компилятора шаблонов ошибки, поэтому я попытался переключиться по частям.

Сначала я попытался переключить только boost::shared_ptr на std::shared_ptr, это не удалось, потому что boost::bind не будет работать с std::shared_ptr без специализации шаблона get_pointer<typename T> для std::shared_ptr (см.: Как разрешить конфликт между boost::shared_ptr и использованием std::shared_ptr?).

После переключения на std::shared_ptr я переключился на std::bind, на этот раз используя std::placeholders< /a>, (спасибо, Ричард) код примера теперь компилируется и работает правильно.

Чтобы использовать std::bind с boost::asio, убедитесь, что std::shared_ptr и std::placeholders также используются.

person mark    schedule 02.03.2012