1.2 仿函数(function call操作符)

  从函数指针到仿函数。

  1.1 函数调用操作符(C++语法中的左右括号)也可以被重载。

  许多STL算法都提供了两个版本,一个用于一般状况(例如排序时以递增方式排列),一个用于特殊状况(例如排序时由使用者指定以何种特殊关系进行排列)。像这种情况,需要用户指定某个条件或策略,而条件或策略的背后由一整组操作构成,便需要某种特殊的东西来代表这“一整组操作”。

   代表“一整组操作”的,是函数。在旧式C语言中,欲将函数当做参数传递,唯有通过函数指针才能达成。例子如下:

#include <cstdlib>
#include <iostream>
using namespace std;

int fcmp(const void* elem1, const void* elem2);

int main(){
    int ia[10] = {32, 97, 62, 22, 43, 25, 52, 59, 54, 9};

    for (int i=0; i<10; i++)
        cout << ia[i] << " ";

    cout << endl;

    qsort(ia, sizeof(ia)/sizeof(int), sizeof(int), fcmp);

    for (int i=0; i<10; i++)
        cout << ia[i] << " ";

    return 0;
}

int fcmp(const void* elem1, const void* elem2){
    const int* i1 = (const int*)elem1;
    const int* i2 = (const int*)elem2;

    if(*i1 < *i2)
        return -1;
    else if(*i1 == *i2)
        return 0;
    else if(*i1 > *i2)
        return 1;
}

  函数指针的缺点:无法持有自己的状态(局部状态),也无法达到组件技术中的可适配性——也就是无法再将某些修饰条件加诸于其上而改变其状态。

  1.2 为此,引入仿函数的概念。STL算法的特殊版本所接受的所谓“条件”或“策略”或“一整组操作”,都以仿函数形式呈现。

  针对某个class进行operator()重载,它就成为一个仿函数。

  例子如下:

 1 #include <iostream>
 2 using namespace std;
 3
 4 // 由于将operator()重载了,因此plus成为了一个仿函数
 5 template <class T>
 6 struct PLUS {
 7     T operator() (const T& x, const T& y) const {return x + y;}
 8 };
 9
10 // 由于将operator()重载了,因此minus成为了一个仿函数
11 template <class T>
12 struct MINUS {
13     T operator() (const T& x, const T& y) const {return x - y;}
14 };
15
16 int main(){
17     // 产生仿函数对象
18     PLUS<int> plusObj;
19     MINUS<int> minusObj;
20
21     // 使用仿函数,就像使用一般函数一样
22     cout << plusObj(3, 5) << endl;
23     cout << minusObj(3, 5) << endl << endl;
24
25     // 直接产生仿函数的临时对象(第一对小括号),并调用(第二对小括号)
26     cout << PLUS<int>() (7, 6) << endl;
27     cout << MINUS<int>() (7, 6) << endl;
28 }

  上述的 PLUS<T> 和 MINUS<T> 已经非常接近STL的实现了,唯一的差别在于它缺乏“可适配能力”。

  1.3 如果要成为一个可适配的仿函数呢?

  将在读完第8章再进行总结。

时间: 2024-10-13 05:12:24

1.2 仿函数(function call操作符)的相关文章

STL——前闭后开区间表示法和function call 操作符

前开后闭开区间表示法[) 任何一个STL算法,都需要获得由一对迭代器(泛型指针)所标示的区间,用以表示操作范围,这一对迭代器所标示的是个所谓的前闭后开区间,以[first,last)表示,也就是说,整个实际范围从first开始,直到last-1.迭代器last所指的是“最后一个元素的下一位置”.这种off by one(偏移一格,或说pass the end)的标示法,带来了很多方便,例如下面两个STL算法的循环设计,就显得干净利落: template<class InputIterator,c

STL源码分析--仿函数 &amp; 模板的模板参数 &amp; 临时对象

STL源码分析-使用的一些特殊语法 关于泛型编程中用到的一些特殊语法,这些语法也适用于平常的模板编程 1.  类模板中使用静态成员变量 Static成员变量在类模板中并不是很特殊,同时这个变量不属于对象,属于实例化以后的这个类类型.每一个实例化对应一个static变量 2.  类模板中可以再有模板成员 3.  模板参数可以根据前一个模板参数而设定默认值 4.  类模板可以拥有非类型的模板参数 所谓非类型的模板参数就是内建型的模板参数 Template <class T,class Alloc =

[c++primer][14]重载操作符与转换

14.1 重载操作符的定义 不能重载的操作符:.  ?:  sizeof  ::  .* 不能为任何内置类型定义额外的新的操作符:优先级和结合性是固定的:不再具备短路求值特性(不建议重载&&.||.逗号): 一般将算术和关系操作符定义为非成员函数,而将赋值操作符定义为成员: 使用重载操作符的方式: 1)  与内置类型使用操作符方式一样: 2)  也可像调用普通函数一样调用重载操作符函数,指定函数并传递适当类型适当数目的形参: item1 += item2; // expression ba

函数调用操作符(operator())

 许多STL算法都需要用户指定某个条件或某个策略,而条件或策略的背后由一整组操作构成,便需要某种特殊的东西来代表这"一整组操作". 代表"一整组操作"的,当然是函数.过去C语言时代,欲将函数当做参数传递,唯有通过函数指针才能达成.但是函数指针有缺点,最重要的是它无法持有自己的状态(所谓局部状态),也无法达到组件技术中的可适配性(adaptablity)-----也就是无法再将某些修饰条件加诸于其上而改变其状态.为此,STL算法的特殊版本所接受的所谓"条

STL学习一:标准模板库理论基础

STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. STL的从广义上讲分为三类:algorithm(算法).container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝 地连接.几乎所有的代码都采 用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会.在C++标准中,STL被组织为下面的13个头文

STL学习_配接器篇

STL学习_配接器篇 定义 配接器(Adapter)在STL组件的灵活组合运用功能上,扮演着轴承.转换器的角色.它事实上是一种设计模式.即将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作. 分类 STL所提供的各种适配器中,改变仿函数(functors)接口者,称为function adapter:改变容器(containers)接口者,称为container adapter:改变迭代器(iterators)接口者,称为iterato

《泛型编程与stl》笔记

以下是STL六大组件(componments): adapters  配接器 用来修饰其他组件.包括iterator adapters.function adapters.container adapters三大类. allocators 配置器 用来分配空间.空间可来自于内存或磁盘--取决于配置器如何 实现.主要用来服务容器. algorithms 算法 如sort,bineary search,permutation.... containers 容器 就是数据结构,用来存放元素.如vect

noobSTL-1-配置器-1

noobSTL-1-配置器-1 1.要点分析 1.1 可能让你困惑的C++语法 组态 即配置. 临时对象 一种无名对象.有时候会刻意地制造临时对象. 静态常量整数成员在class内部直接初始化 const成员:只能在构造函数后的初始化列表中初始化(C++98). C++11提供了类内初始化,因此内类常量可在声明类时进行类内初始化,因此该类内常量的作用域属于类级,即该类的所有对象均具有同一个值. static成员:初始化在类外,且不能加static修饰. const static成员:类只有唯一一

C++ STL学习——vector

学过C++的人肯定会很熟悉STL标准模板库,STL其实就是封装了一系列的接口,供我们调用.很多函数或者算法的实现不需要我们从头开始写,大大提高我们的编程效率.这篇博客在简单介绍STL的情况下,会详细的来介绍vector的使用. STL共有六大组件: 一.容器(Container):是一种数据结构,如list,vector,deque,queue等,以模板类的方法提供,为了访问容器中的数据,可以使用由容器类提供的迭代器. 二.迭代器(Iterator):提供了访问容器中对象的方法. 三.算法(Al