###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 ...
随机推荐
- 转载Jquery中的三种$()
1.$()可以是$(expresion),即css选择器.Xpath或html元素,也就是通过上述表达式来匹配目标元素. 比如:$("a")构造的这个对象,是用CSS选择器构建了一 ...
- 线段树—Lazy_Tag
转载LINK:LAZY_TAG 先看一个具体问题吧 PKU 3468 http://poj.org/problem?id=3468 题意很清楚 1 ≤ N,Q ≤ 100000. "C a ...
- (二)list或set的遍历
<@e.table class="tablelist questionlist" listAction="devide_check_list_batch.do&qu ...
- 按要求编写一个Java应用程序: (1)定义一个类,描述一个矩形,包含有长、宽两种属性,和计算面积方法。 (2)编写一个类,继承自矩形类,同时该类描述长方体,具有长、宽、高属性, 和计算体积的方法。 (3)编写一个测试类,对以上两个类进行测试,创建一个长方体,定义其长、 宽、高,输出其底面积和体积。
package jvxing; public class Jvxing { //成员变量 private double width; private double chang; public doub ...
- iOS UDID和UUID详解
这篇是普及知识来了,纯属消遣时间,有需要的可以遛一遛. UDID的全名为 Unique Device Identifier :设备唯一标识符.从名称上也可以看出,UDID这个东西是和设备有关的,而且是 ...
- 我的第一篇博客 ——【ToDoList】小程序开发
我是一只即将大四的大三狗,这是我的第一篇博客,说来惭愧.今年1月份,学校放寒假的时候开始自学的IOS,放假的时候比较起劲,看了一堆Object-C的视频,然后照着中英文对照的IOS基础开发教程,做了两 ...
- python(6)
python(6) 6.1 面向对象编程:OOP相信学过编程的就会了解它有多重要了.当然c什么的就算了 实际上面向对象就是把对象拥有的数据和方法封装在对象里面,由对象调用. 面向对象最重要的是类 ...
- Android develop tricks——整理自国外的一些Blog
ViewDragHelper --视图拖动是一个比較复杂的问题.这个类能够帮助解决不少问题.假设你须要一个样例,DrawerLayout就是利用它实现扫滑.Flavient Laurent 还写了一些 ...
- 【转】使用junit进行单元测试(初级篇)
转自:http://blog.csdn.net/andycpp/article/details/1327147 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在 ...
- 新浪旗下的SAE云服务入门
前言: 云服务已经火热很多年了,到了现在已经基本进入稳定期,稍微有实力的公司都会推出免费的云存储,像百度的还几个T,速度也不错.如果不担心数据安全问题,代替平时的U盘还是没有问题.而SAE是新浪在20 ...