Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::bind() error: cannot determine which instance of overloaded function "boost::asio::io_service::run" is intended

Tags:

c++

c++11

boost

While trying to compile this in Visual C++ 2015

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

I'm getting errors:

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'

Additionally, IntelliSense complains with:

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

I see that there are 2 overloads of boost::asio::io_service::run. But how can I specify which one to use?

With boost::bind the code compiles just fine:

  auto worker = boost::bind(&boost::asio::io_service::run, &(this->service));
like image 209
rustyx Avatar asked Jan 27 '16 13:01

rustyx


1 Answers

Since boost::asio::io_service::run has two overloads, you need to specify which to use when using it as a function pointer(1). This needs to be done by casting it to the right function signature:

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

Since this looks horrible, I suggest to use a lambda instead of the bind expression. Inside a lambda, the normal overload resolution takes place, so you don't need to specify the overload explicitly:

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

(1) The problem is that std::bind takes the function by an unrestricted template argument, so the rules of template type deduction apply instead of overload resolution. C++ can't determine what the type of _Fx should be here, since you pass something whose type is not specified. Even if there was a trick such that C++ can try to resolve the overload when using the fact that the bound arguments are going to be passed to the function, note that actually both overloads are possible here: The overload with boost::system::error_code & ec would simply be not bound and "curried" instead (specifying the value for that parameter is delayed to the point when worker is called).

like image 59
leemes Avatar answered Sep 24 '22 03:09

leemes