• C++11function


    头文件:<functional>

    function模板库:用于替代C语言中的函数指针,它允许用户在目标的实现上有更大的弹性,即目标既可以是普通函数,也可以是函数对象和类的成员函数。

    注意:function模板类为C++11中的新标准,在编译时注意加上 -std=c++0x 的编译选项,

    适配器bind的实现:

    1.bind()函数。可以固化(绑定)目标函数的行参。(对于类成员函数,可以固化一个对象参数,使其退化为普通函数。)
    2.占位符。可以在bind时保留部分参数不立即固定,起到减少参数数目、交换参数顺序等适配器功能。


    一、普通函数:

    首先我们给出一个普通的函数:

    void foo(const string &s)
    {
        cout << s << endl;
    }

    我们就可以在main函数中这样使用function

    function<void(const string &s)> f =&foo;
    f("world");

    测试结果为:world。上面function可以解释为:

    声明并初始化了一个function,它返回的类型为void,并接受一个const string类型的参数,并且使 f 初始化为foo函数的地址。


    二、类成员函数:

    我们定义一个类,代码如下:

    class Foo
    {
        public:
            void foo(int a)
            {
                cout << a << endl;
            }
    };

    我们采用了以下一种调用方式:

    //头文件
    #include <iostream>
    #include <string>
    #include <functional>
    using namespace std;
    //main函数
    int main(int argc, const char *argv[])
    {
        Foo f;
    //1
        (mem_fun(&Foo::foo)(&f,123));
    //2    
        function<void(int)> pf =
            bind(&Foo::foo,
                 &f,
                 placeholders::_1);
        pf(345);
    //3
        function<void(Foo*, int)> pf2 =bind(&Foo::foo,
                      std::placeholders::_1,
                      std::placeholders::_2);
        pf2(&f,345);
    
        return 0;
    }

    方式一:mem_fun,参见C++类的成员函数的指针和mem_fun适配器的用法
    方式二:

    function<void(int)> pf =bind(&Foo::foo, &f, placeholders::_1);

    适配器的实现:

    首先,bind 是一种 函数适配器 ,它可以改变参数的个数,顺序
    其次,bind中的参数依次为,类Foo的成员函数的地址、类Foo的一个对象f的地址,参数int 的占位符。

    占位符_1、_2指的是实际函数调用实参的位置。而且,占位符必须是接连出现的,不可跳跃使用,bind 中的参数列表可以是 _1,_2,_3 .... 也可以是_1,_3,_2(即次序可以打乱),但是绝对不可以是这样的bind(&Foo::foo, _1, _3)

    方式三:

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

    由于类的成员函数有个隐式参数this。所以,foo函数的实际参数有两个。
    而,第三种方式把this这个隐式参数显示指出;故this对应bind中的占位符_1,int对应占位符_2.

    三、实例:

    #include <iostream>
    #include <string>
    #include <functional>
    using namespace std;
    using namespace std::placeholders;
    
    void test(int i, double d, const string &s)
    {
        cout << "i=" << i << " d=" << d << " s="
            << s << endl;
    }
    
    int main(int argc, const char *argv[])
    {
        function<void(int, double, const string &)>f1 = &test;
        f1(1, 3.14, "foo");
            
    //1
        //void(*)(int, double)
        function<void(double, int, const string &s)> f2 =  bind(&test, _2, _1, _3);
        f2(4.14, 2, "hello");
    //2
        function<void(int, double) > f3= bind(&test, _1, _2, "world");
        f3(3, 5.14);
    //3    
        function<void(const string&, int )> f4 = bind(&test, _2, 6.14, _1);
        f4("how", 4);
    //4    
        function<void(const string&, int, double)> f5 = bind(&test, _2, _3, _1);
        f5("are", 5, 7.14);
    //5
        function<void(int)> f6 = bind(&test, _1, 8.14, "you");
        f6(6);
    //6   
        function<void(const string &)> f7 =bind(&test, 7,9.14,_1);
        f7("thank");
    //7
        function<void()> f8 = bind(&test, 8, 10.14, "foobar");
        f8();
        return 0;
    }
  • 相关阅读:
    ASP.Net核心对象HttpRequest
    HTTP状态码和常用对照表
    Http协议之Get和Post的区别
    Http协议之Request和Response
    HTTP协议的几个概念
    表单内容提交到数据库案例
    关于表单提交的规则
    HttpHandler简介
    DHCP(五)
    DHCP(四)
  • 原文地址:https://www.cnblogs.com/xfxu/p/4018127.html
Copyright © 2020-2023  润新知