如何将派生类中的成员函数作为回调传递?

How can I pass a member function from a derived class as a callback?

本文关键字:回调 函数 成员 派生      更新时间:2023-10-16

我有一个简单的类X

class X {
public:
template<typename T>
void doSomething(T &completion) {
std::cout << completion(10) << std::endl;
}
};

和班级AB

class A {
public: 
// some code
X* c;
};
class B : public A {
public:
int test(int x) {
return x * x;
}
void execute() {
auto lambda = [] (int x) { cout << x * 50 << endl; return x * 100; };
c->doSomething(lambda); // works
c->doSomething(&B::test); // does not work
}
};

我想将类B(或从A派生的任何其他类(的成员方法传递给doSomething方法,但它不起作用:/

如何将派生类中的成员函数作为回调传递?

你的问题与B是儿童班无关。您的问题是您没有将非静态成员函数test()绑定到其实例。

您可以通过使用std::bind返回函子来轻松解决此问题:

c->doSomething(std::bind(&B::test, this, std::placeholders::_1));

不要忘记#include <functional>

或者使用 lambda 通过将this放入lambda捕获中来包装调用:

c->doSomething([this](int x){ return this->test(x); });

注意:确保将doSomething()的参数更改为右值引用,以便它可以在临时对象和其他对象中正确获取所有这些回调优点。应如下所示:

template<typename T>
void doSomething(T&& completion)

使B::test成为静态方法,它将按编写方式工作:

static int test(int x) {
return x * x;
}
// ...
c->doSomething(&B::test);

这是因为静态方法不需要隐式实例(this指针(。

如果B::test必须是常规方法,则必须使用捕获 lambda 传递实例,如下所示:

c->doSomething([this] (int x) { return this->test(x); });

注意:在编译此代码时,我需要更改您对doSomething的定义以关闭T&

template<typename T>
void doSomething(T completion) {
std::cout << completion(10) << std::endl;
}

这可以防止对函数指针类型放置 l 值或非常量约束,这可能会阻止编译器创建临时 lambda 函数。

你是说c->doSomething([this](int x) { return this->test(x); });吗?