http://www.cnblogs.com/yyxt/p/3987717.html

详细请看《C++ Primer plus》(第六版中文版)

http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html

备注:

函数对象:
尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“函数符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。
用函数对象代替函数指针有几个优点:

  首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用结果的数据成员。在使用普通函数时需要将先前调用的结果存储在全程或者本地静态变量中,但是全程或者本地静态变量有某些我们不愿意看到的缺陷。

  其次,在函数对象中编译器能实现内联调用,从而更进一步增强了性能。这在函数指针中几乎是不可能实现的。

  C++11还提供了limbda表达式来实现函数的灵活调用。详见《C++ Primer Plus》第18章。

----------------------------------------------------------------------------------------------------------------------------------------------------------

【以下转自】http://www.cnblogs.com/hujian/archive/2012/12/07/2807605.html

function是一组函数对象包装类的模板,实现了一个泛型的回调机制。function与函数指针比较相似,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数,也可以是函数对象和类的成员函数,而且可以给函数添加状态。
声明一个function时,需要给出所包装的函数对象的返回值类型和各个参数的类型。比如,声明一个function,它返回一个bool类型并接受一个int类型和一个float类型的参数,可以像下面这样:
function<bool (int, float)> f;

下面简要介绍一下function的比较重要的几个接口。

function();

缺省构造函数,创建一个空的函数对象。如果一个空的function被调用,将会抛出一个类型为bad_function_call的异常。

template <typename F> function(F g);

这个泛型的构造函数接受一个兼容的函数对象,即这样一个函数或函数对象,它的返回类型与被构造的function的返回类型或者一样,或者可以隐式转换,并且它的参数也要与被构造的function的参数类型或者一样,或者可以隐式转换。注意,也可以使用另外一个function实例来进行构造。这样做,并且function g为空,则被构造的function也为空。使用空的函数指针和空的成员函数指针也会产生空的function。如果这样做,并且function g为空,则被构造的function也为空。使用空的函数指针和空的成员函数指针也会产生空的function。

template <typename F> function(reference_wrapper<F> g);

这个构造函数与前一个类似,但它接受的函数对象包装在一个reference_wrapper中,用以避免通过值来传递而产生函数或函数对象的一份拷贝。这同样要求函数对象兼容于function的签名。
function& operator=(const function& g);
赋值操作符保存g中的函数或函数对象的一份拷贝;如果g为空,被赋值的函数也将为空。
template<typename F> function& operator=(F g);
这个泛型赋值操作符接受一个兼容的函数指针或函数对象。注意,也可以用另一个 function 实例(带有不同但兼容的签名)来赋值。这同样意味着,如果g是另一个function实例且为空,则赋值后的函数也为空。赋值一个空的函数指针或空的成员函数指针也会使function为空。
bool empty() const;
这个成员函数返回一个布尔值,表示该function是否含有一个函数或函数对象。如果有一个目标函数或函数对象可被调用,它返回 false 。因为一个function可以在一个布尔上下文中测试,或者与0进行比较,因此这个成员函数可能会在未来版本的库中被取消,你应该避免使用它。
void clear();
这个成员函数清除 function, 即它不再关联到一个函数或函数对象。如果function已经是空的,这个调用没有影响。在调用后,function肯定为空。令一个function为空的首选方法是赋0给它;clear 可能在未来版本的库中被取消。
result_type operator()(Arg1 a1, Arg2 a2, ..., ArgN aN) const;
调用操作符是调用function的方法。你不能调用一个空的 function ,那样会抛出一个bad_function_call的异常。调用操作符的执行会调用function中的函数或函数对象,并返回它的结果。
下面分别给出使用function来包装普通函数,函数对象和类的成员函数的参考代码。
1、普通函数
1 int Add(int x, int y)
2
3 {
4             return x+y;
5 }
6 function<int (int,int)> f = Add;
7 int z = f(2, 3);

2、函数对象

 1 class CStudent2 {3 public:4             void operator() (string strName, int nAge)5             {6                 cout << strName << " : " << nAge << endl; 7             }8 };9
10 CStudent stu;
11 function<void (string, int)> f = stu;
12 f("Mike",  12);

3、类的成员函数

 1 struct TAdd2 {3     int Add(int x,int y)4     {5         return x+y;6     }7 };8 9 function<int  (TAdd *, int, int)> f = TAdd::Add;
10 TAdd tAdd;
11 f(&tAdd, 2, 3);   // 如果前面的模板参数为传值或引用,直接传入tAdd即可

接下来我们来看看使用function来保存函数对象状态的情况。考虑下面的代码:

 1 class CAdd2 {3 public:4     CAdd():m_nSum(0) { NULL; }5     int operator()(int i)  //重载 () 运算符6     {7           m_nSum += i;8           return m_nSum;9     }
10
11     int Sum() const
12     {
13         return m_nSum;
14     }
15
16 private:
17     int m_nSum;
18 };
19
20 int main()
21 {
22     CAdd add;
23     function<int (int)> f1 = add;
24     function<int (int)> f2 = add;
25     cout << f1(10) << "," << f2(10) << "," << add.Sum() << endl;
26     return 0;
27 }

可能和大家想象的结果不一样,上面程序的输出是:10,10,0。我们将同一个函数对象赋值给了两个function,然后分别调用了这两个function,但函数对象中m_nSum的状态并没有被保持,问题出在哪儿呢?这是因为function的缺省行为是拷贝一份传递给它的函数对象,于是f1和f2中保存的都是add对象的拷贝,调用f1和f2后,add对象中的值并没有被修改。

C++ 11中提供了ref和cref函数,来提供对象的引用和常引用的包装。要使function能够正确地保存函数对象的状态,我们可以这样来修改代码:

1 CAdd add;
2 function<int(int)> f1 = ref(add);
3 function<int(int)> f2 = ref(add);
另外,在两个function之间赋值时,如果源function保存的是函数对象的拷贝,则目标function保存的也是函数对象的拷贝;如果源function保存的是函数对象的引用,则目标function保存的也是函数对象的引用。

C++11新特性之八——函数对象function相关推荐

  1. c++11新特性的使用---可变模板参数、type_traits、function综合使用

    DLL帮助类 c++中手动调用dll是比较繁琐的,调用过程是:加载dll后还要定义一个对应的函数指针类型,接着调用GetProAddress获取函数地址,在转成函数指针,最后调用该函数如下例子: #i ...

  2. C++ C++基础语法入门总结(二)引用-内联函数-C++11新特性

    C++基础语法入门总结 C++引用 再谈引用和指针 C++内联函数 附加C++11新特性 auto关键字 基于范围的for循环 指针空值nullptr C++引用 引用:就是某一变量(目标)的一个别名 ...

  3. C++11新特性中的匿名函数Lambda表达式的汇编实现分析(二)

    2019独角兽企业重金招聘Python工程师标准>>> C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一) 首先,让我们来看看以&方式进行变量捕获,同样没有参 ...

  4. C++11 新特性简介

    1.auto auto是旧关键字,在C++11之前,auto用来声明自动变量,表明变量存储在栈,很少使用.在C++11中被赋予了新的含义和作用,用于类型推断. auto关键字主要有两种用途:一是在变量 ...

  5. C++11新特性以及std::thread多线程编程

    一 .C++11新特性 1. auto 类型推导 1.1 当=号右边的表达式是一个引用类型时,auto会把引用抛弃,直接推导出原始类型: 1.2 当=号右边的表达式带有const属性时,auto不会使 ...

  6. C++11新特性选讲 语言部分 侯捷

    C++11新特性选讲 语言部分 侯捷 本课程分为两个部分:语言的部分和标准库的部分.只谈新特性,并且是选讲. 本文为语言部分笔记. 语言 Variadic Templates move semanti ...

  7. 【C/C++】C++98基础上的C++11新特性

    一.新语法 1.自动类型推导auto auto的自动推导,用于从初始化表达式中推断出变量的数据类型. //C++98 int a = 10; string s = "abc"; f ...

  8. php7 断言,PHP7.2常用新特性和函数

    通过这篇你将了解PHP 7.2版本中添加的一些新特性和函数. PHP 7.2是一个LTS版本,他提供了一些新功能和几个较小的核心改进.开箱即用的PHP 7.2为我们提供了新的哈希,类型提示,类型扩展和 ...

  9. 【C++】C++11 新特性

    目录 1.列表初始化 1.1. C++98中使用{}初始化的问题 1.2. 内置类型的列表初始化 1.3. 自定义类型的列表初始化 2. 变量类型推导 2.1. 为什么需要类型推导 2.2. decl ...

最新文章

  1. Ajax简单的请求数据以表格的形式渲染到页面
  2. 关于AttributeError: module ‘numpy‘ has no attribute ‘integer‘的解决方法
  3. python用什么软件编程1001python用什么软件编程-怎样才能写出 Pythonic 的代码 #P1001#...
  4. POJ 1655 Balancing Act (求树的重心)【树形DP】(经典)
  5. Install Shield制作安装包技巧(SQL篇)
  6. SQL性能优化案例分析
  7. 第二个冲刺期的第六天
  8. 年底圣诞促销,商家必备节日大促psd分层海报模板
  9. 程序员最应该读的图书
  10. Django 配置App特定类的富文本编辑器
  11. wps怎么免费导出简历_简历怎么写 简历模板word免费下载
  12. 计算机视觉前沿技术探索
  13. 上传图片到淘宝 API
  14. 第2章 先从看得到的入手,探究活动
  15. 吃鸡降落伞降落,射线检测,触发销毁降落伞等
  16. 计算机的操作系统是什么与什么的接口,计算机中操作系统是什么的接口
  17. 订单BOM、销售BOM、标准BOM
  18. ProPresenter 6 for Mac破解版永久激活方法
  19. Rethinking the Smaller-Norm-Less-Informative Assumption in Channel Pruning of Convolution Layers简记
  20. 机器学习之决策树(机器学习技法)

热门文章

  1. bzoj4152: [AMPPZ2014]The Captain
  2. 开窍小老虎,一步一个脚印之 初识汇编(一)
  3. 转:Google论文之三----MapReduce
  4. centos7 python3安装numpy_centos 7 下安装numpy、scipy等python包
  5. z490 linux raid,华硕z490主板装win7系统及bios设置教程(支持10代usb驱动)
  6. android手机最低内存,原神手机端需要哪些配置 手机端最低配置要求介绍
  7. 网上linux实验平台,Linux操作系统实验教程
  8. i2c通信 msp430g2553_关于msp430G2553的I2C串行通信
  9. python多大孩子可以学_孩子学编程最佳年龄是多大
  10. windows2012同步linux时间,Windows server2012时间同步NTP配置