zoukankan      html  css  js  c++  java
  • 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个小练习,相信对于简单的函数适配器已经可以应付了。

    完毕

  • 相关阅读:
    阿里云服务器ECS centos_7 安装jdk环境
    Spring Data Jpa 投影(Projection)的用法
    win10 docker 部署微服务
    centos 安装docker
    VMware 启动 虚拟机后一直黑屏
    VMware 新建虚拟机选择操作系统的时候提示,此主机不支持64位客户机操作系统,此系统无法运行
    mysql 表名全变小写的解决(windows)
    docker: Error response from daemon: driver failed programming external connectivity on endpoint jovial_morse (71d0315110605c3812f7255c7072f5d38512118a4635feaf84cdc170d3bee8d1): Error starting userland
    win10 docker部署springboot项目
    nginx failed (1113: No mapping for the Unicode character exists in the target multi-byte code page)
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4018042.html
Copyright © 2011-2022 走看看