正常回调函数使用的是普通函数或者静态函数,而成员函数因为会在参数列表最前面插入一个 this 指针,所以导致直接使用会报错。成员函数想要被调用需要使用特殊的操作方法。
1. 接收成员函数作为参数
需要使用 std::function
来预先确定成员函数的返回值和参数列表。具体代码如下:
typedef std::function<void(int,int)> Fun;
class B{
public:
void call(int a,Fun f)
{
f(a,2);
}
};
2. 把具体的成员函数配置下去
需要使用 std::bind
来把具体的成员函数和参数位置一起生成和上一步对应的,然后才能配置过去。具体代码如下:
using namespace std::placeholders;
class Test{
public:
void callback(int a,int b)
{
cout<<a<<"+"<<b<<"="<<a+b<<endl;
}
void bind()
{
Fun fun=std::bind(&Test::callback,this,_1,_2);
B b;
b.call(1,fun);
}
};
完整例子如下:
#include <iostream>
#include <functional>
using namespace std;
typedef std::function<void ()> fp;
void g_fun()
{
cout<<"g_fun()"<<endl;
}
class A
{
public:
static void A_fun_static()
{
cout<<"A_fun_static()"<<endl;
}
void A_fun()
{
cout<<"A_fun()"<<endl;
}
void A_fun_int(int i)
{
cout<<"A_fun_int() "<<i<<endl;
}
//非静态类成员,因为含有this指针,所以需要使用bind
void init()
{
fp fp1=std::bind(&A::A_fun,this);
fp1();
}
void init2()
{
typedef std::function<void (int)> fpi;
//对于参数要使用占位符 std::placeholders::_1
fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);
f(5);
}
};
int main()
{
//绑定到全局函数
fp f2=fp(&g_fun);
f2();
//绑定到类静态成员函数
fp f1=fp(&A::A_fun_static);
f1();
A().init();
A().init2();
return 0;
}
参考: https://blog.csdn.net/hyp1977/article/details/51784520 https://blog.csdn.net/this_capslock/article/details/38564719 https://blog.csdn.net/hanxiucaolss/article/details/89500738 https://www.jianshu.com/p/8b6de1e99fc2