ошибка std::bind (): не удается определить, какой экземпляр перегруженной функции "boost:: asio:: IO service:: run" предназначен

при попытке скомпилировать это в Visual C++ 2015

  auto worker = std::bind(&boost::asio::io_service::run, &(this->service));

Я получаю ошибки:

error C2783: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Ret'
note: see declaration of 'std::bind'

error C2783: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx'
note: see declaration of 'std::bind'

error C2783: 'std::_Binder<std::_Unforced,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx'
note: see declaration of 'std::bind'

кроме того, IntelliSense жалуется:

cannot determine which instance of overloaded function "boost::asio::io_service::run" is intended

Я вижу, что есть 2 перегрузки boost::asio::io_service::run. Но как я могу указать, какой из них использовать?

С boost::bind код компилируется просто замечательно:

  auto worker = boost::bind(&boost::asio::io_service::run, &(this->service));

1 ответов


С boost::asio::io_service::run имеет две перегрузки, необходимо указать, что при использовании его в качестве указателя на функцию(1). Это необходимо сделать, приведя его к правой сигнатуре функции:

static_cast<std::size_t(boost::asio::io_service::*)()>(&boost::asio::io_service::run)

поскольку это выглядит ужасно, я предлагаю использовать лямбду вместо выражения bind. Внутри лямбды происходит нормальное разрешение перегрузки, поэтому вам не нужно явно указывать перегрузку:

auto worker = [this]{ return service.run(); };

(1) проблема это std::bind принимает функцию неограниченным аргументом шаблона, поэтому вместо разрешения перегрузки применяются правила вычета типа шаблона. C++ не может определить, какой тип _Fx должно быть здесь, так как вы передаете что-то, тип которого не указан. Даже если был такой трюк, что C++ может попытаться разрешить перегрузку при использовании того факта, что связанные аргументы будут переданы функции, обратите внимание, что на самом деле обе перегрузки возможны здесь: перегрузка с boost::system::error_code & ec будет просто не связан и вместо этого" curried " (указание значения для этого параметра задерживается до точки, когда worker называется).