我必须使用 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));
下面的代码有效,但我觉得行 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));