C++11 function使用
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模板,它给予我们在调用的方式上更大的弹性。
请看一下三种不同的函数定义:
- int add(int a, int b){
- return a+b;
- }
- auto mod=[](int a, int b){return a%b;};
- struct divide{
- int operator()(int m, int n){
- return m/n;
- }
- };
这三种都可以使用同一种调用形式,int(int, int),调用方式如下:
- function<int(int,int)> func1= add;
- function<int(int,int)> func2= divide();
- function<int(int,int)> func3= mod;
- cout<<func1(5, 6)<<endl;
- cout<<func2(5, 6)<<endl;
- cout<<func3(5, 6)<<endl;
学会了使用function,可以继续如下进行抽象定义,不同类型采用相同的调用方法:
- map<string,function<int(int, int)>> funs =
- {
- {"+", add},
- {"-", std::minus<int>()},//标准库的函数,参数为两个整数,可以参考前一篇博客
- {"/", divide()},//类成员函数
- {"*", [](int i,int j){return i*j;}},//lambda表达式
- {"%", mod},
- };
- funs["+"](4,6);
以上就是function的简单使用。下面是从另一篇博客转载的,使用function的引用来保存函数对象。考虑下面代码:
- class CAdd
- {
- public:
- CAdd():m_nSum(0){NULL;}
- int operator()(int i)
- {
- m_nSum += i;
- return m_nSum;
- }
- int Sum() const
- {
- return m_nSum;
- }
- private:
- int m_nSum;
- };
- int main(int argc, const char * argv[])
- {
- CAdd cAdd;
- function<int(int)> funcAdd1 = cAdd;
- function<int(int)> funcAdd2 = cAdd;
- cout<<funcAdd1(10)<<endl;
- cout<<funcAdd2(10)<<endl;
- cout<<cAdd.Sum()<<endl;
- return 0;
- }
上面的输出结果是 10 10 0。我们将同一个函数对象赋值给了两个function,然后分别调用这两个function,但函数中的成员变量的值没有保存,问题在哪里?因为function的缺省行为是拷贝一份传递给它的函数对象,于是f1,f2中保存的都是cAdd对象的拷贝。
C++11提供了ref和cref函数来提供对象的引用和常引用的包装。要是function能够正确保存函数对象的状态,可以如下修改代码:
- function<int(int)> funcAdd3 = ref(cAdd);
- function<int(int)> funcAdd4 = ref(cAdd);
- cout<<funcAdd3(10)<<endl;
- cout<<funcAdd4(10)<<endl;
- cout<<cAdd.Sum()<<endl;
另外,两个function之间赋值时,如果源function保存的是函数对象的拷贝,则目标function保存的也是函数对象的拷贝。如果源function保存的是对函数对象的引用,则目标function保存的也是函数对象的引用。
最新文章
- 关于ubuntu16无线网卡RTL8723BE频繁掉线及信号不足的解决办法
- AXUre
- PHP 小方法之 显示 今天 昨天 上周 上月 近三月 的时间
- paip.提升用户体验--提升java的热部署热更新能力
- 20145211 《Java程序设计》第8周学习总结——自在飞花轻似梦
- Layout No collapsible
- Javascript之三种按钮点击事件
- Sublime Text 插件 autoprefixer
- 1047 - Neighbor House(简单线性DP)
- Repeater绑定数据库
- 减小Cookie体积
- java排序算法(五):快速排序
- java---interrupt、interrupted和isInterrupted的区别
- [codeforces 804F. Fake bullions]
- SpringBoot-目录及说明
- 自定义 绑定响应函数 解除响应函数 .addEventListener 兼容 .attachEvent
- 基于geohash6编码实现相邻4、9、16网格合并
- PAT 乙级 1069 微博转发抽奖(20) C++版
- LOJ-10099(点双联通)
- 上传文件夹+php
热门文章
- 了解固态硬盘SSD,竟然如此简单!小白也能懂!
- JAVA基础数组
- bzoj 4026 dC Loves Number Theory 主席树+欧拉函数
- 一个简单的java年龄计算器
- php第二十五节课
- UVA - 1611 Crane (思路题)
- [bzoj4027][HEOI2015][兔子与樱花] (树形dp思想+玄学贪心)
- [luoguP2701] [USACO5.3]巨大的牛棚Big Barn(DP)
- hdu 3062 2-sat
- VNC Viewer 设置屏幕分辨率-解决屏幕分辨率问题