zoukankan      html  css  js  c++  java
  • C++之std::function与std::bind

    一、std::function

    1、概念

     std::function是一个函数包装器模板,最早来自boost库,对应其boost::function函数包装器。在c++0x11中,将boost::function纳入标准库中。该函数包装器模板能包装任何类型的可调用元素(callable element),例如普通函数和函数对象。包装器对象可以进行拷贝,并且包装器类型仅仅只依赖于其调用特征(call signature),而不依赖于可调用元素自身的类型。

    转载:https://www.cnblogs.com/heartchord/p/5017071.html

    • std::function 是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。
    • 定义格式:std::function<函数类型>。
    • std::function可以取代函数指针的作用,因为它可以延迟函数的执行,特别适合作为回调函数使用。它比普通函数指针更加的灵活和便利。
    链接:https://www.jianshu.com/p/f191e88dcc80

    2、包装不同函数

    ①、包装普通函数

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    int g_Minus(int i, int j)
    {
        return i - j;
    }
    
    int main()
    {
        function<int(int, int)> f = g_Minus;
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

    ②、包装模板函数

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    template <class T>
    T g_Minus(T i, T j)
    {
        return i - j;
    }
    
    int main()
    {
        function<int(int, int)> f = g_Minus<int>;
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

    ③、包装lambda表达式

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    auto g_Minus = [](int i, int j){ return i - j; };
    
    int main()
    {
        function<int(int, int)> f = g_Minus;
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

    ④、包装函数对象

           非模板类型:

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    struct Minus
    {
        int operator() (int i, int j)
        {
            return i - j;
        }
    };
    
    int main()
    {
        function<int(int, int)> f = Minus();
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

           模板类型:

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    template <class T>
    struct Minus
    {
        T operator() (T i, T j)
        {
            return i - j;
        }
    };
    
    int main()
    {
        function<int(int, int)> f = Minus<int>();
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

    ⑤、包装类静态成员函数

           非模板类型:

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    class Math
    {
    public:
        static int Minus(int i, int j)
        {
            return i - j;
        }
    };
    
    int main()
    {
        function<int(int, int)> f = &Math::Minus;
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

           模板类型:

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    class Math
    {
    public:
        template <class T>
        static T Minus(T i, T j)
        {
            return i - j;
        }
    };
    
    int main()
    {
        function<int(int, int)> f = &Math::Minus<int>;
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

    ⑥、包装类对象成员函数

           非模板类型:

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    class Math
    {
    public:
        int Minus(int i, int j)
        {
            return i - j;
        }
    };
    
    int main()
    {
        Math m;
        function<int(int, int)> f = bind(&Math::Minus, &m, placeholders::_1, placeholders::_2);
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

           模板类型:

    复制代码
    #include <iostream>
    #include <functional>
    using namespace std;
    
    class Math
    {
    public:
        template <class T>
        T Minus(T i, T j)
        {
            return i - j;
        }
    };
    
    int main()
    {
        Math m;
        function<int(int, int)> f = bind(&Math::Minus<int>, &m, placeholders::_1, placeholders::_2);
        cout << f(1, 2) << endl;                                            // -1
        return 1;
    }
    复制代码

    转载:https://www.cnblogs.com/heartchord/p/5017071.html

    二、std::bind

    1、概念

    可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

    std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。

    链接:https://www.jianshu.com/p/f191e88dcc80
     
    概括:设置可调用对象(函数)的某些参数为可变变量,将某些参数设置为固定值,然后将整个调用对象返回成std::funciton类型
     
    2、举例
    #include <random>
    #include <iostream>
    #include <memory>
    #include <functional>
     
    void f(int n1, int n2, int n3, const int& n4, int n5)
    {
        std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '
    ';
    }
     
    int g(int n1)
    {
        return n1;
    }
     
    struct Foo {
        void print_sum(int n1, int n2)
        {
            std::cout << n1+n2 << '
    ';
        }
        int data = 10;
    };
     
    int main()
    {
        using namespace std::placeholders;  // for _1, _2, _3...
     
        std::cout << "demonstrates argument reordering and pass-by-reference:
    ";
        int n = 7;
        // (_1 and _2 are from std::placeholders, and represent future
        // arguments that will be passed to f1)
        auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
        n = 10;
        f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
                        // makes a call to f(2, 42, 1, n, 7)
     
        std::cout << "achieving the same effect using a lambda:
    ";
        auto lambda = [ncref=std::cref(n), n=n](auto a, auto b, auto /*unused*/) {
            f(b, 42, a, ncref, n);
        };
        lambda(1, 2, 1001); // same as a call to f1(1, 2, 1001)
     
        std::cout << "nested bind subexpressions share the placeholders:
    ";
        auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
        f2(10, 11, 12); // makes a call to f(12, g(12), 12, 4, 5);
     
        std::cout << "common use case: binding a RNG with a distribution:
    ";
        std::default_random_engine e;
        std::uniform_int_distribution<> d(0, 10);
        auto rnd = std::bind(d, e); // a copy of e is stored in rnd
        for(int n=0; n<10; ++n)
            std::cout << rnd() << ' ';
        std::cout << '
    ';
     
        std::cout << "bind to a pointer to member function:
    ";
        Foo foo;
        auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
        f3(5);
     
        std::cout << "bind to a pointer to data member:
    ";
        auto f4 = std::bind(&Foo::data, _1);
        std::cout << f4(foo) << '
    ';
     
        std::cout << "use smart pointers to call members of the referenced objects:
    ";
        std::cout << f4(std::make_shared<Foo>(foo)) << ' '
                  << f4(std::make_unique<Foo>(foo)) << '
    ';
    }



    长风破浪会有时,直挂云帆济沧海!
    可通过下方链接找到博主
    https://www.cnblogs.com/judes/p/10875138.html
  • 相关阅读:
    python之mysqldb模块安装
    消失的那3个月__怎么看代码的小结
    四年测试经验总结
    python学习笔记系列----(八)python常用的标准库
    业务逻辑中的测试总结(二)----业务与数据库交互需求的测试分解
    python学习笔记系列----(七)类
    【QUESTION】
    python学习笔记系列----(六)错误和异常
    python学习笔记系列----(五)输入和输出
    Android6.0.1 移植:显示系统(一)--测试framebuffer
  • 原文地址:https://www.cnblogs.com/judes/p/14923765.html
Copyright © 2011-2022 走看看