• C++——function和bind的一些应用


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

    我们可以这样使用function模板:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <functional>
    using namespace std;
    
    void foo(const string &s)
    {
        cout << s << endl;
    }
    
    
    int main(int argc, const char *argv[])
    {
        void (*pFunc) (const string &) = &foo;
        pFunc("bar");
    
        function<void (const string&)> f = &foo;
        f("bar");
        
    
        return 0;
    }

    这样f()函数与函数指针pFunc()的作用是一样的,我们可以通过传递对应的参数来调用函数。

    在使用function模板时,我们可以通过调用bind()函数来改变参数的个数、顺序等。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()函数中,我们首先传递要绑定的函数地址,然后根据我们重新定义的函数即function<void (Foo*, int)> pF2来确定我们的参数个数及顺序。

    void foo(int i);
    function<void (Foo*, int)> pf2 = bind(&Foo::foo,
                                              std::placeholders::_1,
                                              std::placeholders::_2);

    由于foo()函数是类成员函数,它有一个隐式参数,所以我们原函数含有两个参数。根据function模板,我们需要按照Foo *, int的顺序传递参数,在原函数中,
    Foo *是第一个参数,对应放置的位置为1, int是第二个参数, 对应的位置为2, 这样,我们调用std::palceholders::来将参数的位置确定下来。

    占位符_1_2指的是实际函数调用实参的位置

    下面是一个有三个参数的函数对应的各种function可能,我们可以从中自己体会,也可以自己尝试重新实现以下。

    代码如下:

     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 #include <functional>
     5 using namespace std;
     6 
     7 void test(int i, double d, const string &s)
     8 {
     9     cout << "i = " << i << " d = " << d << " s = " << s << endl;
    10 }
    11 int main(int argc, const char *argv[])
    12 {
    13     function<void (int, double, const string&)> f1 = &test;
    14     f1(12, 3.14, "foo");
    15 
    16     //1.void (*)(int, double)
    17     function<void (int, double)> f2 =
    18     std::bind(&test, std::placeholders::_1, std::placeholders::_2, "foo");
    19     f2(12, 3.14);
    20 
    21     //2.void (*)(double, int, const string &)
    22     function<void (double, int, const string &)> f3 =
    23     std::bind(&test, std::placeholders::_2, std::placeholders::_1, std::placeholders::_3);
    24     f3(3.14, 12, "foo");
    25 
    26     //3.void (*)(const string &, int)
    27     function<void (const string &, int)> f4 =
    28     std::bind(&test, std::placeholders::_2, 3.14, std::placeholders::_1);
    29     f4("foo", 12);
    30 
    31     //4. void (*) (const string &, int, double)
    32     function<void (const string &, int, double)> f5 =
    33     std::bind(&test, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
    34     f5("foo", 12, 3.14);
    35 
    36     //5. void (*)(int)
    37     function<void (int)> f6 =
    38     std::bind(&test, std::placeholders::_1, 3.14, "foo");
    39     f6(12);
    40 
    41     //6 void(*)(const string &)
    42     function<void (const string &)> f7 =
    43     std::bind(&test, 12, 3.14, std::placeholders::_1);
    44     f7("foo");
    45 
    46     //7. void (*)()
    47     function<void ()> f8 =
    48     std::bind(&test, 12, 3.14, "foo");
    49     f8();
    50 }
    View Code
  • 相关阅读:
    个人介绍
    2021-03-16 助教小结
    2020软件工程作业05
    2020软件工程作业04
    2020软件工程作业03
    第二次作业 计划与执行
    从蓝天到名利 所有你想要的 都别随风去
    Android Task 相关
    Android ViewDragHelper源码解析
    android利用反射通过代码收缩通知栏
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4015554.html
Copyright © 2020-2023  润新知