普通回調
#include<stdio.h> void printWelcome(int len) { printf("welcome -- %d\n", len); } void printGoodbye(int len) { printf("byebye-- %d\n", len); } void callback(int times, void (* print)(int)) { int i; for (i = 0; i < times; ++i) { print(i); } printf("\n welcome or byebye !\n"); } void main(void) { callback(10, printWelcome); callback(10, printGoodbye); }
類成員函數回調
#include <iostream> #include <functional> using namespace std; using namespace std::placeholders; typedef std::function<void(int,int)> Fun; class B{ public: void call(int a,Fun f) { f(a,2); } }; 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); } }; int main() { Test test; test.bind(); return 0; }
bind函數
一般常用語法是: newFunName=bind(oldFunName,arg_list);
bind函數返回一個新的函數對象。其中bind第一個參數是oldFunName,它是待綁定的函數名,arg_list是oldFunName的參數列表。注意,這個參數列表是舊函數的參數列表,前面提到,返回的是子函數。我們可以隨便給子函數定幾個參數,但是肯定不能多於bind所綁定的原函數的參數個數。舉個例子:
//g是一個有兩個參數的可調用對象 auto g=bind(f,a,b,_2,c,_1); //其中f是具有5個參數的函數 //當我們調用g(x,y)時,實際調用的是f(a,b,y,c,x)
上面出現的_1,_2是它的占位符,bind最多可以使用9個占位符。這個占位符命名在std的placeholders中,使用時,要使用using std::placeholders.
function函數
function是一個函數對象的“容器”。
如function<int(int,int)> fun; fun是一個函數模板,可以接受兩個int型參數,並返回一個int型參數。平時可以將它賦值給一個函數指針。
又一個栗子
#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; }
參考於:
http://blog.csdn.net/hyp1977/article/details/51784520