首页 > 代码库 > C++学习之路: 函数适配器

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)> f541         = 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个小练习,相信对于简单的函数适配器已经可以应付了。

 

完毕

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