函數對象實質上是一個實現了operator()--括號操作符--的類。
class Add { public: int operator()(int a, int b) { return a + b; } }; int main() { Add add; // 定義函數對象 cout << add(3, 2); // 5 system("pause"); return 0; }
函數指針版本就是:
int AddFunc(int a, int b) { return a + b; } typedef int(*Add) (int a, int b); int main() { Add add = &AddFunc; cout << add(3, 2); // 5 //(*add)(3,2) system("pause"); return 0; }
既然函數對象與函數指針在使用方式上沒什么區別,那為什么要用函數對象呢?很簡單,函數對象可以攜帶附加數據,而指針就不行了。
下面就舉個使用附加數據的例子:
class Less { public: Less(int num) :n(num) {} bool operator()(int value) { return value < n; } private: int n; }; int main() { Less isLess(10); cout << isLess(9) << " " << isLess(12); // 輸出 1 0 system("pause"); return 0; }
bind是這樣一種機制,它可以預先把指定函數的某些參數綁定到已有的變量,產生一個新的函數,這種機制在回調函數的使用過程中也頗為有用。
int Func(int x, int y) { return x + y; } int main() { //bf1把擁有兩個參數的普通函數的第一個參數綁定為10,生成了一個新的一個參數的函數 auto bf1 = std::bind(Func, 10, std::placeholders::_1); cout<<bf1(20); ///< same as Func(10, 20) system("pause"); return 0; }
class A { public: int Func(int x, int y) { return x + y; } }; int main() { A a; //bf2把一個類成員函數綁定了類對象,生成了一個像普通函數一樣的新的可調用實體 auto bf2 = std::bind(&A::Func, a, std::placeholders::_1, std::placeholders::_2); cout << bf2(10, 20); ///< same as a.Func(10, 20) system("pause"); return 0; }
使用bind需要注意的一些事項:
- (1)bind預先綁定的參數需要傳具體的變量或值進去,對於預先綁定的參數,是pass-by-value的
- (2)對於不事先綁定的參數,需要傳std::placeholders進去,從_1開始,依次遞增。placeholder是pass-by-reference的
- (3)bind的返回值是可調用實體,可以直接賦給std::function對象
- (4)對於綁定的指針、引用類型的參數,使用者需要保證在可調用實體調用之前,這些參數是可用的
- (5)類的this可以通過對象或者指針來綁定
參考:http://blog.csdn.net/crayondeng/article/details/9996625
