我有一个简单的课程X
class X {
public:
template<typename T>
void doSomething(T &completion) {
std::cout << completion(10) << std::endl;
}
};
以及类A
和B
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
}
};
我想将doSomething
类(或从B
派生的任何其他类)的成员方法传递给A
方法,但是它不起作用:/
答案 0 :(得分:5)
如何将派生类中的成员函数作为回调传递?
您的问题与B
是儿童班无关。您的问题是您没有将非静态成员函数 test()
绑定到其实例。
您可以通过using std::bind
轻松返回此地址,以返回 functor :
c->doSomething(std::bind(&B::test, this, std::placeholders::_1));
别忘了#include <functional>
,
或使用 lambda 通过将this
放在lambda captures中来包装呼叫:
c->doSomething([this](int x){ return this->test(x); });
注意:确保将doSomething()
的参数更改为 rvalue引用,以便可以在临时对象和其他对象中正确利用所有这些回调特性。应该看起来像这样:
template<typename T>
void doSomething(T&& completion)
答案 1 :(得分:3)
将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值或非const约束,从而可以防止编译器创建临时lambda函数。
答案 2 :(得分:1)
您是说c->doSomething([this](int x) { return this->test(x); });
吗?