我必须使用 lambda 将成员函数作为 std::function 传递吗?

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

下面的代码有效,但我觉得行 worker([this](int a, long b, int* c){receiver(a, b, c);}); 有点多余,因为它重复了 receiver 的签名。我可以通过某种方式直接传递成员函数,而不是传递一个依次调用成员函数的 lambda 函数吗?

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)
    {
    }
};

std::bind 是经典方法,它避免了明确说明转发签名的需要:

using namespace std::placeholders;

// ...

    worker(std::bind(&Caller::receiver, this, _1, _2, _3));

C++20也有std::bind_front;它在一定程度上减少了这种冗长。

您不能“直接”将指针传递给成员函数。这是因为成员函数需要一个 specific 对象实例,其成员函数应该被调用。因此,以某种形式,以某种方式,您无法避免 this 或该对象的某些其他实例参与该过程。这是 C++ 的基础。这里唯一能做的就是找点语法糖,这里基本上就是这些了。

如果你可以访问 C++20,请使用 bolov 的答案。 如果没有...

虽然这仍然使用 lambda,但您可以利用参数包来避免重复签名:

worker([this](auto... params) { receiver(params...); });

这需要 C++14 或更新版本。

如果你的类型比较复杂,想避免复制,可以加完美转发:

worker([this](auto&&... params) {
    receiver(std::forward<decltype(params)>(params)...);
});

最干净的方式是 C++20 的 std::bind_front:

worker(std::bind_front(&Caller::receiver, this));