1. 程式人生 > >C++11函數綁定

C++11函數綁定

綁定器 stat public lac 一個 其中 IT turn names

函數綁定:
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 }


C++11函數綁定