I have the following scenario quite often in my c++17 code.
Generic example:
class Receiver{
public:
typedef std::function<void(const std::vector<uint8_t>& payload)> PROCESS_PACKET;
PROCESS_PACKET m_callback;
void run(){
while(){
// do stuff, then call callback:
m_callback(data);
}
}
};
class UsesReceiver{
public:
UsesReceiver(){
receiver.m_callback=std::bind(&UsesReceiver::processData, this, std::placeholders::_1);
receiver.run();
}
private:
void processData(const std::vector<uint8_t>& payload){
// here do something implementation specific
}
Receiver receiver;
};
What always bugs me is this part:
receiver.m_callback=std::bind(&UsesReceiver::processData, this, std::placeholders::_1);
For this example it is quite simple, since the function only takes one parameter, but as soon as you have more parameters this part is a lot of boilerplate in my opinion.
Because I am thinking: If there is a member function whoese definition is exactly the same as the declared function pointer (e.g. arguments and function type match) there should be a simple one-liner that checks these preconditions at compile time and looks basically like this:
receiver.m_callback=std::bind_quick(&UsesReceiver::processData,this);
Where std::bind_quick, is "just like std::bind" but without placeholders if both function declarations match (checked at compile time).
Since the first couple of comments were "use lambdas instead": This doesn't really solve the problem, because with lambdas you still have to declare "placeholders" for your function arguments:
receiver.m_callback=[this](auto && PH1) {
processData(std::forward<decltype(PH1)>(PH1));
};