function是一组函数对象包装类的模板,实现了一个泛型的回调机制。

引入头文件

#include <functional>
using namespace std;
using namespace std::placeholders;  //bind的时候会用`

参考:http://www.cnblogs.com/hujian/archive/2012/12/07/2807605.html

fuction  bind:http://blog.csdn.net/fjb2080/article/details/7527715

我们可以调用的对象有很多,比如普通函数、函数指针、lanmbda表达式、函数对象和类的成员函数等。

不管采用哪种方式,主要调用形式一样(返回值类型、传递给调用的实参类型),我们就可以使用同一种形式来调用。

这个时候就可以用到function模板,它给予我们在调用的方式上更大的弹性。

请看一下三种不同的函数定义:

  1. int add(int a, int b){
  2. return a+b;
  3. }
  4. auto mod=[](int a, int b){return a%b;};
  5. struct divide{
  6. int operator()(int m, int n){
  7. return m/n;
  8. }
  9. };

这三种都可以使用同一种调用形式,int(int, int),调用方式如下:

  1. function<int(int,int)> func1= add;
  2. function<int(int,int)> func2= divide();
  3. function<int(int,int)> func3= mod;
  4. cout<<func1(5, 6)<<endl;
  5. cout<<func2(5, 6)<<endl;
  6. cout<<func3(5, 6)<<endl;

学会了使用function,可以继续如下进行抽象定义,不同类型采用相同的调用方法:

  1. map<string,function<int(int, int)>> funs =
  2. {
  3. {"+", add},
  4. {"-", std::minus<int>()},//标准库的函数,参数为两个整数,可以参考前一篇博客
  5. {"/", divide()},//类成员函数
  6. {"*", [](int i,int j){return i*j;}},//lambda表达式
  7. {"%", mod},
  8. };
  9. funs["+"](4,6);

以上就是function的简单使用。下面是从另一篇博客转载的,使用function的引用来保存函数对象。考虑下面代码:

  1. class CAdd
  2. {
  3. public:
  4. CAdd():m_nSum(0){NULL;}
  5. int operator()(int i)
  6. {
  7. m_nSum += i;
  8. return m_nSum;
  9. }
  10. int Sum() const
  11. {
  12. return m_nSum;
  13. }
  14. private:
  15. int m_nSum;
  16. };
  17. int main(int argc, const char * argv[])
  18. {
  19. CAdd cAdd;
  20. function<int(int)> funcAdd1 = cAdd;
  21. function<int(int)> funcAdd2 = cAdd;
  22. cout<<funcAdd1(10)<<endl;
  23. cout<<funcAdd2(10)<<endl;
  24. cout<<cAdd.Sum()<<endl;
  25. return 0;
  26. }

上面的输出结果是 10 10 0。我们将同一个函数对象赋值给了两个function,然后分别调用这两个function,但函数中的成员变量的值没有保存,问题在哪里?因为function的缺省行为是拷贝一份传递给它的函数对象,于是f1,f2中保存的都是cAdd对象的拷贝。

C++11提供了ref和cref函数来提供对象的引用和常引用的包装。要是function能够正确保存函数对象的状态,可以如下修改代码:

  1. function<int(int)> funcAdd3 = ref(cAdd);
  2. function<int(int)> funcAdd4 = ref(cAdd);
  3. cout<<funcAdd3(10)<<endl;
  4. cout<<funcAdd4(10)<<endl;
  5. cout<<cAdd.Sum()<<endl;

另外,两个function之间赋值时,如果源function保存的是函数对象的拷贝,则目标function保存的也是函数对象的拷贝。如果源function保存的是对函数对象的引用,则目标function保存的也是函数对象的引用。

C++11 function使用的更多相关文章

  1. C++11 Function 使用场景

    [1]场景分析 在一个函数内部,可能会多次用到某一段代码,一般情况是把这段用到次数较多的代码封装成一个函数. 但是,如果这段代码仅仅只在这个函数中有使用,这时封装成函数显得既麻烦又冗赘. 那么,有没有 ...

  2. Using C++11 function & bind

    The example of callback in C++11 is shown below. #include <functional> void MyFunc1(int val1, ...

  3. C++11 function

    #include <iostream> #include <functional> #include <vector> using namespace std; / ...

  4. c++11 function bind 测试。

    实验小结 1)function 是一个模板类.有函数指针成员.可以看作安全型函数指针. template<typename _Res, typename... _ArgTypes> cla ...

  5. c++11:function的用法

    function是函数.函数对象.函数指针.和成员函数的包装器,可以容纳任何类型的函数对象,函数指针,引用函数,成员函数的指针 普通函数 #include <functional> voi ...

  6. C++ 11: function & bind 使用示例

    #include <functional> #include <iostream> struct Foo { Foo(int num) : num_(num) {} void ...

  7. C++11 function用法 可调用对象模板类

    std::function<datatype()> ()内写参数类型 datatype 代表function的返回值 灵活的用法.. 代码如下 #include <stdio.h&g ...

  8. C++11绑定器bind及function机制

    前言 之前在学muduo网络库时,看到陈硕以基于对象编程的方式,大量使用boost库中的bind和function机制,如今,这些概念都已引入至C++11,包含在头文件<functional&g ...

  9. JavaScript function函数种类(转)

    转自:http://www.cnblogs.com/polk6/p/3284839.html JavaScript function函数种类 本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通 ...

随机推荐

  1. Java实现打包文件

    把文件打包到压缩包里 public void zip (String... files) throws IOException { //创建文件打包流对象 ZipOutputStream zos = ...

  2. 浅谈GFC

    Web页面的布局,我们常见的主要有“浮动布局(float)”.“定位布局(position)”.“行内块布局(inline-block)”.“CSS3的多栏布局(Columns)”.“伸缩布局(Fle ...

  3. Linux(Centos7) 设置静态IP

    关于虚拟机 这里使用Centos7为例,因为linux是安装在在虚拟机中,这里先看一下虚拟机的网络适配器: 这里我使用的NAT模式,接着配置虚拟机的虚拟网络: 这里主要看一下VMnet8的设置: 这里 ...

  4. 迷宫问题 POJ - 3984 (搜索输出路径)

    题目大意 题目不需要大意,poj居然还有中文题 鸣谢 特别鸣谢ljc大佬提供的方法!!! 解法 我们可能输出个最短路径的长度比较简单,但是输出最短路径真的是没有做过,这里有一种简单的方法 因为我们的d ...

  5. PAT 1130 Infix Expression

    Given a syntax tree (binary), you are supposed to output the corresponding infix expression, with pa ...

  6. 处理回车提交、ctrl+enter和shift+enter都不提交->textarea正常换行

    <input type="textarea" @on-keypress="handlerMultiEnter"> handlerMultiEnter ...

  7. [luoguP1879] [USACO06NOV]玉米田Corn Fields(DP)

    传送门 说要统计方案,感觉就是个 Σ 而矩阵中只有 01 ,可以用二进制表示 这样,预处理出每一个每一行所有可能的状态 s 然后初始化第一行所有状态的方案数为 1 f[i][j] = Σf[i - 1 ...

  8. (13)Corner Detection角点检测

    import cv2 import numpy as np img=cv2.imread('opencv-corner-detection-sample.jpg') gray = cv2.cvtCol ...

  9. SQL Server死锁总结 [转]

    1. 死锁原理 根据操作系统中的定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态. 死锁的四个必要条件:互斥条件(Mutua ...

  10. - > 贪心基础入门讲解一——完美字符串

    约翰认为字符串的完美度等于它里面所有字母的完美度之和.每个字母的完美度可以由你来分配,不同字母的完美度不同,分别对应一个1-26之间的整数. 约翰不在乎字母大小写.(也就是说字母F和f)的完美度相同. ...