function/bind 函数适配器

1、function/bind简介

function是一种类模板,重载了operator()函数调用操作符,所以每一个function类的对象都是一个函数对象。

bind是一种函数适配器,可以改变参数的个数、顺序。

2、相关代码

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <functional>
 5 using namespace std;
 6 
 7 void foo(const string &s)
 8 {
 9     cout << s << endl;
10 }
11 
12 
13 int main(int argc, const char *argv[])
14 {
15     void (*pFunc) (const string &) = &foo;
16     pFunc("bar");
17 
18     function<void (const string&)> f = &foo;
19     f("bar");
20     
21 
22     return 0;
23 }

此时pFunc()和f()函数都等价于foo()函数,调用pFunc(),f()相当于调用foo()函数。

接下来我们尝试使用function模板,代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <functional>
 5 using namespace std;
 6 
 7 void foo(int i, double d)
 8 {
 9     cout << i << d << endl;
10 }
11 
12 
13 int main(int argc, const char *argv[])
14 {
15     function<void (int, double)> f = &foo;
16     f(12, 4.5);
17     
18 
19     return 0;
20 }

function和bind联合使用,代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <functional>
 5 using namespace std;
 6 
 7 class Foo
 8 {
 9     public:
10         void foo(int i) { cout << i << endl; }        
11 
12         static void bar(double d) { cout << d << endl; }
13 
14 };
15 
16 int main(int argc, const char *argv[])
17 {
18     //mem_fun void (*)(Foo *, int)
19     Foo f;
20     (mem_fun(&Foo::foo))(&f, 123); 
21 
22     function<void (int)> pf = bind(&Foo::foo, 
23                                    &f, 
24                                    std::placeholders::_1);
25     pf(345);
26 
27     function<void (Foo*, int)> pf2 = bind(&Foo::foo,
28                                           std::placeholders::_1,
29                                           std::placeholders::_2);
30 
31     pf2(&f, 456);
32 
33     function<void (int, Foo*)> pf3 = bind(&Foo::foo,
34                     std::placeholders::_2,
35                     std::placeholders::_1);
36 
37     pf3(567, &f);
38 
39 
40 
41     return 0;
42 }

从上面的代码可以看出bind()可以适配参数的位置和个数。

我们继续看几个代码加深理解。

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <functional>
 5 using namespace std;
 6 using namespace std::placeholders;
 7 
 8 void test(int i, double d, const string &s)//int ,double, const string & 的位置分别为1,2,3
 9 {
10     cout << "i = " << i << " d = " << d << " s = " << s << endl;
11 }
12 int main(int argc, const char *argv[])
13 {
14     function<void (int, double, const string&)> f1 = &test;
15     f1(12, 3.14, "foo");
16 
17     //1.void (*)(int, double)
18     function<void (int, double)> f2 = //bind()的第一个参数永远为指向函数的指针或地址,int对应_1, double对应_2,缺少一个参数对应_3,因此我们在第三个参数位置直接实参
19             std::bind(&test,
20                       _1,
21                       _2,
22                       "foo");
23 
24     //2.void (*)(double, int, const string &)
25     function<void (double, int, const string &)> f3 = 
26         std::bind(&test,    //第一个参数为函数地址即&test, 
27 _2, //double对应test()函数第二个参数,所以bind的第二个参数位置_2 28 _1, 29 _3); 30 31 //3.void (*)(const string &, int) 32 function<void (const string &, int)> f4 = 33 std::bind(&test, 34 _2, 35 3.4, //两个参数缺少一个double参数,double参数在test()中为第二个参数,所以在&test以后的第二个参数位置,写个double实参 36 _1); 37 38 39 //4. void (*) (const string &, int, double) 40 function<void (const string&, int, double)> f5 41 = std::bind(&test, 42 _2, 43 _3, 44 _1); 45 46 //5. void (*)(int) 47 function<void (int)> f6 = 48 bind(&test, 49 _1, 50 3.4, 51 "bar"); 52 53 //6 void(*)(const string &) 54 function<void (const string &)> f7 = 55 bind(&test, 56 12, 57 4.5, 58 _1); 59 60 //7. void (*)() 61 function<void()> f8 = 62 bind(&test, 63 12, 64 4.5, 65 "bar"); 66 }

 

posted @ 2014-10-11 02:03  worseman  阅读(225)  评论(0编辑  收藏  举报