C++学习之路: 函数适配器

引言:

函数适配器也是种模板技术, 通过绑定把函数绑定到适配器上实现函数调用, 并且可以修改参数,和移动参数的位置。功能强大

在这里简单介绍一下这种强大的工具

 

1. 对于普通函数, 直接把它的类型 <返回值 (参数1, 参数2,.......)> 如此填入 适配器当做函数类型即可

  function<返回值 (参数1, 参数2,.......)>  pf = &func ;

  这样定义, pf就变成了func函数, 可以通过下例一样调用。

 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 }

 

2) 双参数普通函数的例子

与上例没什么不同, 不过多了个参数。

 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 }

 

3. 对于类内部的成员函数, 如果没有实例我们就无法访问其成员函数 所以我们必须采用一种强大的工具----》 bind

这里介绍下bind 的接口,   这个bind 不是linux下 绑定套接字的那个bind, 不要混淆, bind返回值是一个函数适配器,  参数bind(参数1:要绑定的函数, 参数2:第一个参数要适配的位置或者要填充的常量, 参数3:第2个参数要适配的位置或者要填充的常量, 第3个参数要适配的位置或者要填充的常量)

 

 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 }

4.对于非类的成员函数同样也可以使用bind来绑定 来达到缺省 参数, 参数调换位置的目的

 

我们可以通过几个小练习来熟悉一下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)
 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 = 
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,
27                   _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,
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 }

 

 

通过以上7个小练习,相信对于简单的函数适配器已经可以应付了。

 

完毕

posted @ 2014-10-10 22:55  tilly_chang  阅读(501)  评论(0编辑  收藏  举报