函数绑定:
1.函数对象
(1.1)能够被当做函数调用的不一定就是函数,它们也可能是:
A.存放函数入口地址的函数指针
B.实现了小括号运算符的类对象,亦称仿函数
C.可被转换为函数指针的类对象
(1.2)可调用对象,像函数指针,仿函数以及可被转换为函数指针的类对象都被称为可调用对象,而他们的类型就被称为可调用类型
(1.3)函数对象,函数对象实际上是一个function类模板的实例化对象,其中封装了以上三种可调用对象的任何一种,
对函数对象的调用,实际就是对被其封装的可调用对象的调用
1 #include "stdafx.h" 2 #include <iostream> 3 #include <functional> 4 using namespace std; 5 6 int fun(int x, int y) 7 { 8 cout << __FUNCTION__ << endl; 9 return x + y; 10 } 11 12 class Foo 13 { 14 public: 15 Foo(void){} 16 Foo(int x, int y) :m_x(x), m_y(y){} 17 int operator()(int x, int y)const 18 { 19 cout << __FUNCTION__ << "1" << endl; 20 return x + y; 21 } 22 int operator()(void)const 23 { 24 cout << __FUNCTION__ << "2" << endl; 25 return m_x + m_y; 26 } 27 private: 28 int m_x, m_y; 29 }; 30 31 class Bar 32 { 33 using mfun_t = int(*)(int, int); 34 public: 35 //operator隐式类型转换 36 operator mfun_t(void)const 37 { 38 return mfun; 39 } 40 private: 41 static int mfun(int x, int y) 42 { 43 cout << __FUNCTION__ << endl; 44 return x + y; 45 } 46 47 }; 48 49 int add(int x, int y, function<int(int, int)>f) 50 { 51 return f(x, y); 52 } 53 54 int _tmain(int argc, _TCHAR* argv[]) 55 { 56 //函数不是可调用的对象 57 cout << fun(123, 456) << endl; 58 //函数指针形式的可调用对象 59 int(*pfunc)(int, int) = fun; 60 cout << pfunc(123, 456) << endl; 61 //仿函数形式的可调用对象 62 Foo foo1; 63 cout << foo1(123, 456) << endl; 64 //cout << foo1.operator()(123,456) << endl; 65 Foo foo2(123,456); 66 cout << foo2() << endl; 67 //可被转换为函数指针的类对象形式的可调用对象 68 Bar bar; 69 cout << bar(123, 456) << endl; 70 71 function<int(int, int)> f1 = pfunc; 72 cout << f1(123, 456) << endl; 73 function<int(int, int)> f2 = foo1; 74 cout << f2(123, 456) << endl; 75 function<int(int, int)> f3 = bar; 76 cout << f3(123, 456) << endl; 77 78 cout << add(111, 222, pfunc) << endl; 79 cout << add(111, 222, foo1) << endl; 80 cout << add(111, 222, bar) << endl; 81 82 getchar(); 83 return 0; 84 }
2.函数绑定器
(2.1)函数绑定器可以将一个可调用对象和期望传递给该可调用对象的全部或者部分参数绑定为一个函数对象,
对该函数对象的调用就是在调用被其绑定的可调用对象。
函数对象 bind(可调用对象,期望参数表)
期望参数表可包含期望传递给可调用对象的0到多个参数
函数对象 <==> 可调用对象(期望参数表)
(2.2)placeholders::_n是一个占位符,其值将由传递给函数对象的第n个(从1开始算)参数取代。
1 #include "stdafx.h" 2 #include <iostream> 3 #include <functional> 4 using namespace std; 5 6 int fun(int x, int y) 7 { 8 cout << __FUNCTION__ << endl; 9 return x + y; 10 } 11 12 class Foo 13 { 14 public: 15 int operator()(int x, int y)const 16 { 17 cout << __FUNCTION__ << endl; 18 return x + y; 19 } 20 }; 21 22 class Bind 23 { 24 public: 25 Bind(int(*pfunc)(int, int), int x, int y) :m_pfunc(pfunc), m_x(x), m_y(y){} 26 int operator()(void)const 27 { 28 return m_pfunc(m_x, m_y); 29 } 30 31 private: 32 int(*m_pfunc)(int, int); 33 int m_x; 34 int m_y; 35 }; 36 37 Bind myBind(int(*pfun)(int, int), int x, int y) 38 { 39 return Bind(pfun, x, y); 40 } 41 42 int _tmain(int argc, _TCHAR* argv[]) 43 { 44 function<int(void)> f1 = bind(fun, 123, 456); 45 cout << f1() << endl; 46 cout << fun(123, 456) << endl; 47 48 Bind f2 = myBind(fun, 123, 456); 49 cout << f2() << endl; 50 51 function<int(int)> f3 = bind(fun,123,placeholders::_1); 52 cout << f3(456) << endl; 53 //function<int(int,int)> f4 = bind(fun, placeholders::_1,placeholders::_2); 54 auto f4 = bind(fun, placeholders::_1, placeholders::_2); 55 cout << f4(123,456) << endl; 56 57 auto f5 = bind(fun, placeholders::_5, placeholders::_3); 58 cout << f5(1, 2, 3, 4, 5, 6, 7, 8, 9) << endl; 59 //cout<<f5(5,3)<<endl; 60 61 auto f6 = bind(Foo(), 111, 222); 62 cout << f6() << endl; 63 //cout<<Foo()(111,222)<<endl; 64 65 using placeholders::_1; 66 using placeholders::_2; 67 68 auto f7 = bind(Foo(), _1, _2); 69 cout << f7(444, 555) << endl; 70 71 getchar(); 72 return 0; 73 }
3.无论类的普通成员函数还是静态成员函数,都可以通过bind与其参数一起绑定为函数对象,
但是要注意作为类的普通成员函数需要连同传递给它的this指针一起绑定。
1 #include "stdafx.h" 2 #include <iostream> 3 #include <vector> 4 #include <algorithm> 5 #include <functional> 6 using namespace std; 7 8 bool IsJige(int score) 9 { 10 return score >= 60; 11 } 12 int _tmain(int argc, _TCHAR* argv[]) 13 { 14 vector<int> scores{ 70, 40, 50, 30, 80, 88, 85, 95, 10, 55,60 }; 15 int jige = 0; 16 for (auto score:scores) 17 if (score >= 60) 18 ++jige; 19 cout << "及格:" << jige << endl; 20 cout << "及格:" << count_if(scores.begin(), scores.end(), IsJige) << endl; 21 cout << boolalpha << less_equal<int>()(60, 60) << endl; 22 cout << less<int>()(60, 60) << endl; 23 using placeholders::_1; 24 cout << "及格:" << count_if(scores.begin(), scores.end(), bind(less_equal<int>(),60, _1)); 25 cout << "不及格:" << count_if(scores.begin(), scores.end(), bind(less<int>(),_1,60)); 26 getchar(); 27 return 0; 28 }