Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Must I use lambda to pass a member function as std::function?

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)
    {
    }
};
like image 277
Damn Vegetables Avatar asked Dec 23 '22 14:12

Damn Vegetables


2 Answers

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)...);
});
like image 144
spectras Avatar answered Apr 27 '23 01:04

spectras


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.

like image 20
Sam Varshavchik Avatar answered Apr 27 '23 01:04

Sam Varshavchik