STL学习笔记(仿函数)
仿函数(Functors)
仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
例如我们定义一个类:
class X{
public:
return-value operator()(arguments) const;
...
};
然后就可以把这个类别的对象当做函数调用
X fo;
...
fo(arg1,arg2) //等价于fo.operator()(arg1,arg2);
显然,这种定义形式更为复杂,却又三大妙处:
1.仿函数比一般函数更灵巧,因为它可以拥有状态。
2.每个仿函数都有其型别。因此可以将仿函数的型别当做template参数传递。
3.执行速度上,仿函数通常比函数指针更快。
仿函数可当做排序准则
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std; class Person{
public:
string firstname() const;
string lastname() const;
...
}; class PersonSortCriterion{
public:
bool operator()(const Person&p1,const Person& p2) const {
return p1.lastname()<p2.lastname()||
(!(p2.lastname()<p1.lastname())&&
p1.firstname()<p2.firstname());
}
}; int main()
{
typedef set<Person,PersonSortCriterion> PersonSet;
PersonSet coll;
PersonSet::iterator pos;
for(pos=coll.begin();pos!=coll.end();++pos){
...
}
...
}
这里的coll适用了特殊排序准则PersonSortCritersion,而它是一个仿函数类别。所以可以当做set的template参数,而一般函数则无法做到这一点。
拥有内部状态的仿函数
下面例子展示仿函数如何模拟函数在同一时刻下拥有多个状态
#include <iostream>
#include <list>
#include <algorithm>
#include "print.cpp"
using namespace std; class IntSequence
{
private:
int value;
public:
IntSequence(int initialValue):value(initialValue){}
int operator() ()
{
return value++;
}
}; int main()
{
list<int> coll;
generate_n(back_inserter(coll),,IntSequence());
PRINT_ELEMENTS(coll);
generate(++coll.begin(),--coll.end(),IntSequence());
PRINT_ELEMENTS(coll);
}
for_each()的返回值
使用for_each()可以返回其仿函数。下面将演示这一点
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; class MeanValue
{
private:
long num;
long sum;
public:
MeanValue():num(),sum(){}
void operator() (int elem)
{
num++;
sum+=elem;
}
double value()
{
return static_cast<double>(sum)/static_cast<double>(num);
}
}; int main()
{
vector<int> coll;
for(int i=;i<=;++i)
{
coll.push_back(i);
}
MeanValue mv=for_each(coll.begin(),coll.end(),MeanValue());
cout<<"mean value:"<<mv.value()<<endl;
}
预定义的仿函数
C++标准程序库提供了许多预定义的仿函数。下面列出了所有这些仿函数
对对象排序或进行比较时,一般都以less<>为预设排序准则。要使用这些仿函数,必须包含头文件<functional>。
函数配接器(Function Adapters)
所谓“函数配接器”是指能够将仿函数和另一个仿函数(或某个值,或一般函数)结合起来的仿函数。函数配接器也声明与<functional>中。
例如以下语句:
find_if(coll.begin(),coll.end(),bind2nd(greater<int>()),)
其中bind2nd是将一个二元仿函数(greater<>)转换成一元仿函数。它通常将第二参数传给“由第一参数指出”的二元仿函数,作为后者的第二参数。
下面列出了预定义的函数配接器
STL学习笔记(仿函数)的更多相关文章
- Effective STL 学习笔记 39 ~ 41
Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...
- Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...
- Effective STL 学习笔记 32 ~ 33
Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 31:排序算法
Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 Item 30: 保证目标区间足够大
Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...
- Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor
Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...
- Effective STL 学习笔记: Item 22 ~ 24
Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...
- Effective STL 学习笔记 Item 21:Comparison Function 相关
Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...
- Effective STL 学习笔记:19 ~ 20
Effective STL 学习笔记:19 ~ 20 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
随机推荐
- 火柴排队(NOIP2013)(附树状数组专题讲解(其实只是粗略。。。))
原题传送门 首先,这道题目是一道神奇的题. 看到这道题,第一眼就觉得2个数组排个序,然后一一对应的时候一定差值最小. 由于我们可以将这2个数列同时进行调换. 所以我们先把2个数列排个序. 第二个序列中 ...
- 华为上机测试题(水仙花数升级版-java)
PS:这题满分100,没有做对,大家帮忙看看问题在哪 /* * 题目:水仙花数升级版 * 描述: 水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身.(例如:1 ...
- kvm虚拟机最佳实践系列1-kvm宿主机准备
KVM宿主机配置 系统环境:ubuntu16, bond0 业务网口 bond1 管理网口+存储网口 安装KVM环境支持 sudo apt-get install qemu-kvm sudo apt- ...
- Activity管理类
package com.yunpai.tms.application; import android.app.Activity; import android.app.ActivityManager; ...
- net页面生命周期
ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维护状态.运行事件处理程序代码以及进行呈现.了解页的生命周期非常重要,这样就能 ...
- (寒假集训)Roadblock(最短路)
Roadblock 时间限制: 1 Sec 内存限制: 64 MB提交: 9 解决: 5[提交][状态][讨论版] 题目描述 Every morning, FJ wakes up and walk ...
- Kali Linux Wine32英文字体不显示问题
Kali Linux Wine32英文字体不显示问题 Kali Linux提供了Wine32工具.在运行Wine32后,界面可以显示中文,但不能显示英文文字.英文文字均显示为方块.这是由于缺少对应的 ...
- BZOJ2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
神奇的莫队算法,用来解决可离线无修改的区间查询问题: 首先对原序列进行分块,√n块每块√n个: 然后对所有查询的区间[l,r]进行排序,首先按l所在的块序号升序排序,如果一样就按r升序排序: 最后就按 ...
- DB2如何调整表空间大小
DB2如何调整表空间大小 刚刚接到客户那边打的电话,程序一直报错,所有的业务都做不了,拷贝了一份应用服务器(weblogic)的日志,日志里显示: WARN : 2009-06-18 16:24:32 ...
- 八. 输入输出(IO)操作2.面向字符的输入流
字符流是针对字符数据的特点进行过优化的,因而提供一些面向字符的有用特性,字符流的源或目标通常是文本文件. Reader和Writer是java.io包中所有字符流的父类.由于它们都是抽象类,所以应使用 ...