###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 ...
随机推荐
- [Objective-c 基础 - 2.11] SEL数据类型
A.概念 1.SEL类型代表方法 2.每个方法都有一个对应的SEL类型的数据 3.实例对象调用方法 (1)编译器会把类的方法包装成SEL类型的数据, (2)根据SEL数据找到方法地址,缓存此地址 (3 ...
- D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建
说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...
- jquery完成带复选框的表格行高亮显示
jquery完成带复选框的表格行高亮显示 通过jquery技术来操作表格是件简单的事,通过jquery的语法,可以很轻松的完成表格的隔行换色,悬浮高亮,在实际的应用中可能会出现表格中带复选框的,删除时 ...
- Winform 注册机通用软件注册功能之建立有效的软件保护机制
本文转载:http://www.cnblogs.com/umplatform/archive/2013/01/23/2873001.html 众所周知,一些共享软件往往提供给使用者的是一个功能不受限制 ...
- 【IOS界面布局】横竖屏切换和控件自适应(推荐)
[IOS界面布局]横竖屏切换和控件自适应(推荐) 分类: [MAC/IOS下开发]2013-11-06 15:14 8798人阅读 评论(0) 收藏 举报 横竖屏切换 自适应 第一种:通过人为的办法改 ...
- Windows Server 2008找回密码
1.通过Windows Server 2008 R2的安装光盘引导计算机启动,映像加载完毕后 ,按 Shift+F10 ,打开命令提示符界面,进入Windows目录所在分区(cd windows\sy ...
- Python 调用C++
1.C++代码提供Python需要的接口: #include "stdafx.h" #include <boost/python.hpp> #include <s ...
- 主流数据库字段类型转.Net类型的方法
最近在阅读一些开源的代码,发现其中有些方法总结的很全面,至少在我做同样的事情时候,需要抓破脑袋想活着google,现在看到了这个关于主流数据库字段类型转.Net类型的方法,故收藏之,也顺便分享给那些能 ...
- [MODx] 5. WayFinder
1. Install the wayFinder package 2. Select the resource which you want to show: The 'published' reso ...
- iOS开发——数据持久化Swift篇&模型对象归档
模型对象归档 import UIKit class ViewController: UIViewController { @IBOutlet weak var textField: UITextFie ...