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; ...
随机推荐
- iOS crash 崩溃问题的追踪方法
http://www.cnblogs.com/easonoutlook/archive/2012/12/27/2835884.html iOS crash 崩溃问题的追踪方法 在调试程序的时候,总是碰 ...
- F28379D烧写双核程序(在线&离线)
烧写双核程序前需知在分别对F28379D的CPU1和CPU2两个核进行烧写程序时,需要在CCS中建立两个工程,独立编写两个核的程序.如controlSUITE中提供的双核程序例程: 1. 在线1.1 ...
- Scala学习随笔——Scala起步
实验楼学习Scala语言的笔记,课程网址为https://www.shiyanlou.com/courses/490 一.Scala简介 Scala 是一门多范式的编程语言,类似于 Java .设计初 ...
- rgmanager 介绍
版本: rgmanager-2.0.52-14.el6.x86_64 服务: /etc/init.d/rgmanager 配置文件: /etc/cluster/cluster.conf 日志文件: 相 ...
- Netty源码学习(四)Netty服务器是如何启动的?
本文会分析Netty服务器的启动过程,采用的范例代码是Netty编写的Echo Server. 0. 声明acceptor与worker 由于Netty采用的reactor模型,所以需要声明两组线程, ...
- 解决win10下微信开发者工具点击错位问题
在系统设置->显示->更改文本.应用等项目的大小选项中将百分比改为100%即可.
- (1)C# 创建ef sqlserver
连接sql 如果报错不能连接的错误 把这三个IP地址的端口号设置上,并启用.第一个18.6是本机ip,之后就可以测试了 最后重启服务器
- Bug预防体系
Web常见产品问题及预防 测试人员在每次版本迭代中,会对项目的整体质量有一个把控,对于项目常见的问题,开发经常犯的错误都会有所了解,为了避免或者减少这样的错误或不规范的事情在发生,测试人员可以整理构建 ...
- 【bzoj3173】【Tjoi2013】【最长上升子序列】treap+dp二分优化
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61560361 向大(hei)佬(e)实力学(di ...
- 为添加了自定义域名的GitHub Pages添加SSL,启用强制HTTPS(小绿锁)
直奔主题 为什么要使用https协议? 提高网站访问安全性,网络连接都是加密的 (PS:虽然SSL并不是无懈可击的,但是我们应该尽可能提高窃听成本). 目前越来越多的浏览器会判断当前站点支不支持htt ...