std::function"函数"对象包装器

语义:

  类模板std::function是可调用对象的包装器,可以包装除了类成员之外的所有可调用对象。包括,普通函数,函数指针,lambda,仿函数。通过指定的模板参数,它可以用统一的方式保存,并延迟执行它们。所谓的延迟执行,就是回调了。

它使得C++对C的兼容性更强了。

常规多态案例:

#include <iostream>
#include <functional>
using namespace std;
class Operator
{
  public:
    virtual int op(int,int) = 0;
};
class OperatorAdd:public Operator
{   public:
    int op(int i,int j)
{
return i+j;
}
};
class OperatorMinus:public Operator
{   public:
    int op(int i,int j)
    {
      return i-j;
    }
};
int main()
{
  Operator *oper = new OperatorAdd;
  cout<<oper->op(4,5)<<endl;
  oper = new OperatorMinus;
  cout<<oper->op(10,4)<<endl;
  return 0;
}

多态转std::function

#include <iostream>
#include <functional>
#include <map>
using namespace std;
int add(int i,int j)
{
    return i+j;
}
int _minus(int i,int j)
{
    return i-j;
}

typedef int(*MINUS)(int,int);//using MINUS =  int(*)(int,int)
auto multiply = [](int i,int j){return i*j;};

class Divide
{
public:
    int operator()(int i, int j){
        return i/j;
    }
};
int main()
{
    std::function<int(int,int)> oper;
    oper = add;
    cout<<oper(1,2)<<endl;
    MINUS m = _minus;
    oper = m;
    cout<<oper(10,1)<<endl;
    oper = multiply;
    cout<<oper(1,2)<<endl;
    oper = Divide();
    cout<<oper(10,2)<<endl;
    map<string,std::function<int(int,int)>> math;
    math.insert({"+",add});
    math.insert({"-",_minus});
    math.insert({"*",multiply});
    math.insert({"/",Divide()});
    math.insert({"%",[](int i, int j){return i%j;}});
    cout<<math["+"](10,5)<<endl;
    cout<<math["-"](10,5)<<endl;
    cout<<math["*"](10,5)<<endl;
    cout<<math["/"](10,5)<<endl;
    cout<<math["%"](10,5)<<endl;
    return 0;
}

  写完这段代码完全被震撼了,被感动的不要不要的。C++的灵活性简直逆天了。

应用:

常规回调

#include <iostream>
#include <functional>
using namespace std;
class functor
{
public:
    void operator()()
    {
        cout<<__FUNCTION__<<endl;
    }
};

class A
{
public:
    A(const function<void()> & cb):_callback(cb)
    {}
    void notify()
    {
        _callback();
    }
    function<void()> _callback;
};
int main(int argc, char *argv[])
{
    functor fct;
    A a(fct);
    a.notify();
    return 0;
}
#include <iostream>
#include <functional>

using namespace std;

void printWhenEven(int data,const std::function<void(int)> &f)
{
    if(data%2)
        f(data);
}

void print(int i)
{
    cout<<i<<endl;
}

int main()
{
    for(int i =0;i<10;i++)
    {
        printWhenEven(i,print);
        cout<<"+++++++++++++++++++"<<endl;
//        printWhenEven(i,[](int i){cout<<i+1<<endl;});
    }
}

原文地址:https://www.cnblogs.com/wangkeqin/p/9338358.html

时间: 2024-10-15 02:22:03

std::function"函数"对象包装器的相关文章

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 = vo

(九)对象包装器与自动装箱

有时候需要将基本数据类型转换为对象,如int -> Integer.Integer这样的类称为对象包装器类,该类一旦构造对象,便是不可变的. 装箱 list.add(3) 自动变为 list.add(Integer.valueOf(3)) 拆箱 int n = list.get(i) 自动变为 int n = list.get(i).intValue() 注意:Integer对象是不可变的,包含在包装器的内容不会改变.不能使用包装器类创建修改数值参数的方法.比如: Integer n = Int

C++11 学习笔记 std::function和bind绑定器

一.std::function C++中的可调用对象虽然具有比较统一操作形式(除了类成员指针之外,都是后面加括号进行调用),但定义方法五花八门.为了统一泛化函数对象,函数指针,引用函数,成员函数的指针的各种操作,让我们可以按更统一的方式写出更加泛化的代码,C++11推出了std::function. std::function是可调用对象的包装器.它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象.通过指定它的模板参数,它可以用统一的方式处理函数,函数对象,函数指针,并允许保存和

对象包装器与自动装箱

前言 前面提到过,除了int,float这些基本数据类型,其他所有数据类型在Java中都是类. 那么,如果我希望这些基本类型也是类类型呢? 那么就使用对象包装器吧. 包装器的作用 1. 它能够提供很多类型转型方面的方法. 2. 泛型数据的成员只能是对象. 自动装箱 就是当你使用某个基础类型,但实际类型要求是它的包装器的时候,编译器不会报错,会帮你自动完成转型. 如: ArrayList <Integer> array = new ArrayList <> (): array.add

js面向对象系列——Function函数对象

Function到底是什么东西? 1. Function是最顶层的构造器,它构造了系统中所有的对象,包括Object(Object是最顶层的对象,但要明确的知道Object也是一个函数,也是有Function构成的),Array,Date等 2. 一切都是对象,所以理论上理解Function也是一个对象,我们可以称为函数对象 这里简单介绍一下另一个重要的工具:instanceof 作用:检验对象的类型 function TestObject(){} TestObject instanceof O

关于Function()函数对象的那些小九九

概念:首先,函数是一种特殊类型的数据,函数也是数据类型的一种,实际上函数也是一种对象,函数对象的内建构造器是Function(); 函数的几种创建方式: 函数声明法: function sum(a,b){ return a+b;  } ; 函数文本标识法 var  sum = function(a,b){ return a+b; }: 函数构造器法 var sum= new Function('a','b','return a+b;') ; 使用函数构造器法创建的函数,其参数和代码段,都是以字符

python3 functools partial 用于函数的包装器详解

一.partial 的作用: partial 用于对一个已有函数进行包装,达到功能的定制的目的. 二.例子: 假设我们要完成两个功能,第一个功能是完成两个数相加,第二个功能是给一个自增一下 1.传统方法,由于自增只是第一个功能的特例我们可以这样写代码: def add(x,y): return x+y if __name__=="__main__": a=100 b=200 c=add(a,b) #实现c=a+b a=add(a,1) #实现a=a+1 这样的实现方式不好,就表现在过几

c++11特性与cocos2d-x 3.0之std::bind与std::function

昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0内的Label锚点是在ccp(0.5,0.5),而一直3.0rc0是ccp(0,0). 累觉不爱.尽管cocos2d-x改变太快,兼容性一次次的暴露出不足,但是,总归是向好的方向进行.于是下载了3.0来玩玩~ cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码:

std::function

参考资料 • cplusplus.com:http://www.cplusplus.com/reference/functional/function/ std::function简介 • 类模板声明 // MS C++ 2013 template<class _Fty> class function; template<class _Fty> class function : public _Get_function_impl<_Fty>::type { ... }