• c++11——std::function和bind绑定器


      c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值。

    可调用对象

    c++中的可调用对象存在以下几类: 
    (1)函数指针 
    (2)具有operator()成员函数的类对象(仿函数) 
    (3)可被转换为函数指针的类对象 
    (4)类成员(函数)指针

    void func(void){
        //....
    }
    
    struct Foo{
        void operator()(void){
            //...
        }
    };
    
    struct Bar{
        using fr_t = void(*)(void);
        static void func(void){ 
            //...
        }
        operator fr_t(void){  //可以进行隐式转换,转换结果为 fr_t 为一个函数指针
            return func;     //operator xxx (void) 函数可以对类的对象进行隐式转换
        }
    };
    
    struct A{
        int a_;
        void mem_func(void){
            //...
        }
    };
    int main(){
        void(* func_ptr)(void) = &func; //1.函数指针
        func_ptr(); 
        
        Foo foo;                //2. 仿函数
        foo();
        
        Bar bar;
        bar();          //可被转化为函数指针的类对象
        
        void (A::*mem_func_ptr)(void) = &A::mem_func; //类成员函数指针
        
        int A::*mem_obj_ptr = &A::a; //类成员指针
        return 0;
    }
    

    可调用对象包装器——std::function

        c++11通过std::function, std::bind统一了可调用对象的各种操作。std::function是可调用对象的包装器,它是一个类模板,可以容纳类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延时执行它们。 
    std::function<返回值(参数类型)> f;

    void func(void){
    }
    class Foo{
    public:
        static int foo_func(int a){
            std::cout << "hello" <<std::endl;
            return a;
        }
    };
    int main(){
        std::function<void(void)> f;
        f = func;
        std::function<int(int)> = Foo::foo_func;
        return 0;
    }
    

    std::bind绑定器

        std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用 std::function进行保存,并延迟调用到任何我们需要的时候。它主要有两大作用: 
    (1)将可调用对象与其参数一起绑定成一个仿函数 
    (2)将多元(参数个数为n>1)可调用对象转成x元( 0 <= 0 <= n)元可调用对象,即只绑定部分参数。 
    (3)使用bind可以将类的非静态成员函数绑定起来,赋值给一个可执行std::function对象

    #include<functional>
    using namespace std;
    
    int func(int a, int b){
    	std::cout << "a = " << a << ", b = " << b << std::endl;
    	return a + b;
    }
    
    class A{
    public:
    	int mem_func(int a, int b){
    		std::cout << "a = " << a << ", b = " << b << std::endl;
    		return a + b;
    	}
    };
    int main(){
    	//直接生成一个可调用对象,然后调用,参数为3
    	//bind(func, 1, std::placeholders::_1)中表示将参数1 和参数 std::placeholders::_1作为函数func的参数,绑定成另一个可执行对象。
    	//在绑定的时候, 按照顺序,1 作为 func(int a, int b) 中形参a的实参; std::placeholders::_1 作为 func(int a, int b) 中形参b的实参
    
    	//std::placeholders::_1 是占位符,表示将绑定后得到的可执行对象进行调用的时候,实参的第1个,放到 std::placeholders::_1的位置上去
    	//依次,std::placeholders::_2 将调用的时候实参的第2个,放到该位置上去
    	//注意,占位符 std::placeholders::_x 中x必须小于等于调用的时候实际参数的个数!!
    	std::bind(func, 1, std::placeholders::_1)(3);		//输出 a = 1, b = 3
    	std::bind(func, 1, std::placeholders::_2)(3, 6);	//输出 a = 1, b = 6
    
    	//用function可调用对象f保存bind后的结果
    	std::function<int(int)> f = std::bind(func, 1, std::placeholders::_1);
    	f(2);		//输出 a = 1, b = 2
    	f = std::bind(func, std::placeholders::_1, 1);	
    	f(3);		//输出 a = 3, b = 1
    	
    	//将类的非静态成员函数,以及类的对象实例,进行绑定
    	A a;
    	f = std::bind(&A::mem_func, a, 1, std::placeholders::_1);
    	f(10);
    	return 0;
    }
    

    使用组合bind函数

        bind可以组合多个函数,假设要找出集合中大于5小于10的元素个数. 
    判断一个数是否大于5的闭包,代码std::bind(std::greater< int>(), std::placeholders::_1, 5) 
    判断一个数是否小于10的闭包,代码std::bind(std::less_equal< int>(), std::placeholders::_1, 10) 
    然后进行组合,得到:

    using std::placeholders::_1;
    //查找集合中大于5小于等于10的元素个数
    auto f = std::bind(
    std::logic_and<bool>(), 
    std::bind(std::greater<int>(), _1, 5),
    std::bind(std::less_equal<int>(), _1, 10));
    
    int count = std::count_if(coll.begin(), coll.end(), f);
    
  • 相关阅读:
    看到关于java资料比较全的,自己收藏
    ie6下pnghack——css方案
    git基本操作
    购物车功能实现
    jquery学习:获取位置position(),offset(),scrollTop困惑
    Datax3.0使用说明
    Scala字符串操作
    Scala中class、object、case class、case object区别
    Scala构造函数
    scala数组操作
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4803205.html
Copyright © 2020-2023  润新知