The following code works, but I feel that the line worker([this](int a, long b, int* c){receiver(a, b, c);});
is sort of redundant because it is repeating the signature of receiver
. Instead of passing a lambda function that in turn calls the member function, can I somehow pass the member function directly?
using callback = std::function<void(int, long, int*)>;
void worker(callback c)
{
c(1,2L,(int*)3);
}
class Caller
{
public:
Caller()
{
worker([this](int a, long b, int* c){receiver(a, b, c);});
}
void receiver(int a, long b, int* c)
{
}
};
CodePudding user response:
If you have access to C 20, use bolov's answer. If not…
Though this still uses a lambda, you can take advantage of an argument pack to avoid duplicating the signature:
worker([this](auto... params) { receiver(params...); });
This requires C 14 or newer.
Perfect forwarding can be added if you have more complex types and want to avoid copies:
worker([this](auto&&... params) {
receiver(std::forward<decltype(params)>(params)...);
});
CodePudding user response:
std::bind
is the classical approach, that avoids the need to explicitly spell out the forwarding signature:
using namespace std::placeholders;
// ...
worker(std::bind(&Caller::receiver, this, _1, _2, _3));
C 20 also has std::bind_front
; it reduces this verbiage, somewhat.
You cannot pass a pointer to a member function "directly". This is because a member function requires a specific instance of an object whose member function should get invoked. So, in some form of fashion, in some way, you cannot avoid this
, or some other instance of the object, to be involved in the process. This is fundamental to C . The only thing that can be done here is to find some syntactic sugar, which is basically all this is, here.
CodePudding user response:
The cleanest way is C 20's std::bind_front
:
worker(std::bind_front(&Caller::receiver, this));