###STL学习--函数对象
点击查看Evernote原文。
#@author: gr
#@date: 2014-08-13
#@email: forgerui@gmail.com
在stl中,函数对象被大量地使用,用以提高代码的通用性及效率。stl也提供了一些常用的函数对象类型。
###stl学习
|--迭代器
|--类属算法
|--容器
|--vector
|--deque
|--list
|--set
|--map
|--函数对象
|--适配器
|--分配器
一、Contents
1. 所谓函数对象
函数对象是行为类似函数的对象。一个类对象,表现出一个函数的特征,即通过对象名+(参数列表)的方式使用一个类对象。
2. 初见函数对象
int sum = add(a, b)可以看做是调用add函数或者使用函数对象,如下:
//1. 完全可以看做是调用add函数
int sum = add(a, b);
//2. 当然也可以看作是使用函数对象,可以通过如下的定义:
Template <class T>
class Add{
public:
T operator() (T a, T b){
return a + b;
}
};
Sum<int> add;s
int sum = add(a, b);
3. 为何要使用函数对象
那么为什么不使用更简单的函数,而选择看起来更复杂的函数对象呢?
在一些情况下,为了使程序富于变化,增加程序的通用性,有时需要将函数当作参数传递,这就需要使用函数指针。
stl类属算法中有一个accumulate函数,其中需要传递一个函数。如下:
//accumulate函数实现,最后一个参数是函数指针
template<typename InputIterator, typename T>
T accumulate(InputIterator first, InputIterator last, T init, T (*binary_function)(T a, T b)){
while(first != last){
init = binary_function(init, *first++);
}
return init;
}
//声明的函数
int product(int a, int b){ return a*b;}
int main(){
int arr[] = {1, 3, 5, 2, 1};
vector<int> vec(arr, arr+6);
//传递声明的函数指针
int product = accumulate(vec.begin(), vec.end(), 1, &product);
}
这样的实现有个问题是通用性不强。函数指针原型可以写为
T (*binary_function) (T a, T b);
这样的函数可以和int product(int, int)匹配,但如果T类型很大,为了提高效率,需要将上面的语句写为如下:
T (*binary_function) (const T& a, const T& b);
则product将**无法与之匹配××,此时必须将函数重写为
int product(const int&, const int&);
另外一个问题在于效率,必须通过指针才能调用这个函数,所以无法使用内联的方式,如果要执行的函数很小,进行一次函数调用将会有相对大的额外开销,而如果这个函数调用是在一个循环中,可以想象出其对效率有严重的影响。
4. 使用函数对象解决问题
现在修改accumulate函数,使用函数对象作为参数。
template <typename InputIterator, typename T, typename FunObj>
T accumulate(InputIterator first, InputIterator last, T init, FunObj obj){
while(first != last){
init = obj(init, *first++);
}
return init;
}
使用这种定义的优点是,可以传递各式各样的类对象,并且可以对operator()进行重载,以匹配多种类型的函数调用,而函数指针则只能接受指定类型的函数,这无疑提高了通用性。
另外,编译器可以对operator()进行内联,从而取消调用函数的开销。
More,使用类对象可以提供额外信息,类对象可以有数据成员,可以记录一些状态,这样可以本地封装信息,而无需采用静态或全局数据来实现...
5. stl中提供的函数对象类
- 算术运算类
plus,minus,multiplies,divides,modules,negate - 比较运算
equal_to,not_equal_to,greater,less,greater_equal,less_equal - 逻辑运算
logical_and,logical_or,logical_not
二、Miscellany
@author gr
@mail forgerui@gmail.com
###STL学习--函数对象的更多相关文章
- C++ STL 之 函数对象适配器
谓词是指普通函数或重载的 operator()返回值是 bool 类型的函数对象(仿函数).如果operator 接受一个参数,那么叫做一元谓词,如果接受两个参数,那么叫做二元谓词,谓词可作为一个判断 ...
- C++ STL 之 函数对象
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载“()”操作符,使得类对象可以像函数那样调用.注意 ...
- 条款20 STL函数对象
继承标准STL的函数对象 1: struct PopLess : public atd::binary_function<state,state,bool> 2: { 3: bool op ...
- STL学习笔记8 -- 函数对象
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个类对象,如果 ...
- STL学习笔记(六) 函数对象
条款38:遵循按值传递的原则来设计仿函数 仿函数都是 pass-by-value Function for_each(InputIterator first, InputIterator last, ...
- 3.2 STL中的函数对象类模板
*: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...
- 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象
总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...
- STL算法设计理念 - 预定义函数对象
预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...
- STL算法设计理念 - 函数对象和函数对象当参数和返回值
函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...
随机推荐
- PTA 5-14 电话聊天狂人 (25分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数NN(\le 10^5≤105),为通话记录条数.随后NN行,每行给出一条通话记录.简单起见,这里只列出 ...
- .NET自带IOC容器MEF之初体验
.NET自带IOC容器MEF之初体验 本文主要把MEF作为一种IOC容器进行讲解,.net中可用的IOC容器非常多,如 CastleWindsor,Unity,Autofac,ObjectBuil ...
- cocos2d-x sprite触摸处理
转自:http://www.cnblogs.com/lancidie/archive/2013/04/01/2993890.html 我们常常需要判断用户的点击操作是否落于某个sprite之上,进而让 ...
- 获取WMI硬件清单
WMI服务能够报告详细的硬件信息.通常,每个硬件都来自它们自己的WMI代理类.但是要找出这些硬件类的名字是不容易. 所有硬件类都在同一个WMI根下面,你可以在根类查询所有的硬件: Get-WmiObj ...
- HubbleDotNet 学习之路
1.创建后台任务实现自动同步更新表数据.打开工具后点击“management”选项卡,选择“task scheduler management”,在弹出的窗口中点击右侧的"add" ...
- jQuery Masonry构建pinterest网站布局注意要点(转)
在愚人码头的博客上看到有关于如何构建pinterest网站的文章,其实就是“图片瀑布流显示”,我试着在本地做了一个,没有什么问题,但是放到公司的网站上就问题多多.一是定位不准确,二是图片显示不完整.但 ...
- [015]staic成员及staic成员函数
C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!这句话可能比较拗口, ...
- 文件和目录之umask函数
本篇博文内容摘自<UNIX环境高级编程>(第二版),仅作个人学习记录所用.关于本书可参考:http://www.apuebook.com/. umask函数为进程设置文件模式创建屏蔽字,并 ...
- GoF的23个经典设计模式
以文本和思维导图的方式简明扼要的介绍了GoF的23个经典设计模式,可当成学习设计模式的一个小手册,偶尔看一下,说不定会对大师的思想精髓有新的领悟. GoF(“四人帮”,又称Gang of Four,即 ...
- AT-Activity
关于Activity的粗略翻译 原地址:Activity 类概述: Activity是独立的.突出的可被用户操作的东西.几乎所有的Activity都是与用户进行交互的,所以这些Activity会很小 ...