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; ...
随机推荐
- python 操作数据库1--连接、执行sql语句
#!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/11/20 16:03 # @Author : lijunjiang # @Fi ...
- poj 1981(单位圆覆盖最多点问题模板)
Circle and Points Time Limit: 5000MS Memory Limit: 30000K Total Submissions: 7327 Accepted: 2651 ...
- laravel中建立公共视图的方法
1.用法概要 @include('common.header') 包含子视图 @extends('article.common.base') 继承基础模板 @yield('content') 视图占位 ...
- [BZOJ1260][CQOI2007]涂色paint 区间dp
1260: [CQOI2007]涂色paint Time Limit: 30 Sec Memory Limit: 64 MB Submit: 1575 Solved: 955 [Submit][S ...
- JDK7集合框架源码阅读(四) LinkedHashMap
基于版本jdk1.7.0_80 java.util.LinkedHashMap 代码如下 /* * Copyright (c) 2000, 2010, Oracle and/or its affili ...
- cl编译C文件的环境变量修改
添 加环境 变量INCLUDEC:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files (x8 ...
- ELK之收集日志到mysql数据库
写入数据库的目的是持久化保存重要数据,比如状态码.客户端浏览器版本等,用于后期按月做数据统计等. 环境准备 linux-elk1:10.0.0.22,Kibana ES Logstash Nginx ...
- Group Shifted Strings -- LeetCode
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- Maximum Product of Word Lengths -- LeetCode
Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the tw ...
- Combination Sum III - LeetCode
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...