Reputation: 486
I face a problem when trying to bind a method with std::function and std::bind.
In my CommunicationService class :
this->httpServer->BindGET(std::bind(&CommunicationService::ManageGETRequest, this, std::placeholders::_1));
CommunicationService::ManageGetRequest signature :
MessageContent CommunicationService::ManageGetRequest(std::string uri, MessageContent msgContent)
BindGET signature :
void RESTServer::BindGET(RequestFunction getMethod)
RequestFunction typedef :
typedef std::function<MessageContent(std::string, MessageContent)> RequestFunction;
The error on BindGET :
error C2664: 'void RESTServer::BindGET(RequestFunction)': cannot convert argument 1 from 'std::_Binder < std::_Unforced,MessageContent (__cdecl communication::CommunicationService::* )(std::string,MessageContent),communication::CommunicationService *const ,const std::_Ph < 1 > & >' to 'RequestFunction'
Before, my RequestFunction was like that :
typedef std::function<void(std::string)> RequestFunction;
and it worked perfectly. (with all signature methods adjusted of course).
I don't understand what causes the error.
Upvotes: 3
Views: 3846
Reputation: 275260
Change
this->httpServer->BindGET(
std::bind(&CommunicationService::ManageGETRequest, this, std::placeholders::_1)
);
to
this->httpServer->BindGET(
[this](std::string uri, MessageContent msgContent) {
this->ManageGETRequest(std::move(uri), std::move(msgContent));
}
);
Using std::bind
is almost always a bad idea. Lambdas solve the same problems, and almost always do it better, and give better error messages. The few cases where std::bind
has features lambdas do not where mostly covered by C++14.
std::bind
was written in pre-lambda C++11 as boost::bind
then brought into the standard at the same time lambdas where. At the time, lambdas had a few limitations, so std::bind
made sense. But this isn't one of the cases where lambdas C++11 limitations occur, and as lambda has grown in power since, learning to use std::bind
has significantly diminished marginal utility at this point.
Even if you master std::bind
, it has enough annoying quirks (like passing a bind expression to bind) that avoiding it has payoff.
You could also fix it with:
this->httpServer->BindGET(
std::bind(&CommunicationService::ManageGETRequest, this, std::placeholders::_1, std::placeholders::_2)
);
but I don't think you should.
Upvotes: 10