STL源码剖析 仿函数

  • 仿函数 也叫函数对象
  • 1,具有函数性质的对象;2,这种东西在调用者可以像函数一样地被调用(调用),在被调用者则以对象所定义的function call operator扮 演函数的实质角色。
  • 要将某种 “操作”当做算法的参数,唯一办法就是先将该"操作” (可能拥有数条以上的指令)设计为一个函数,再将函数指针当做算法的一个参数;或是将该“操作”设计为一个所谓的仿函数(就语言层面而言是个class), 再以该 仿函数产生一个对象,并以此对象作为算法的一个参数.
  • 根据以上陈述,既然函数指针可以达到“将整组操作当做算法的参数”,那又何必有所谓的仿函数呢?原因在于函数指针毕竟不能满足STL对抽象性的要求,也不能满足软件积木的要求—— 函数指针无法和STL其它组件(如配接器adapter, 第8 章)搭配,产生更灵活的变化
  • 就实现观点而言,仿函数其实上就是一个“行为类似函数”的对象。为了能够“行为类似函数”,其类别定义中必须自定义(或说改写、重载)function call运算 子 (operator()  语法和语意请参考1.9.6节).拥有这样的运算子后,我们就 可以在仿函数的对象后面加上一对小括号以此调用仿函数所定义的 operator()

  •  其中第一种用法比较为大家所熟悉,greater<int> i g 的意思是产生一个名为 i g 的对象,ig(4,6)则是调用其operator (),并给予两个参数4,6。第二种用法中的greater<int> ()意思是产生一个临时(无名的)对象,之后的(4,6)才 是指定两个参数4,6。临时对象的产生方式与生命周期,请参见192节。

  •  S T L 仿函数的分类,若以操作数(operand)的个数划分,可分为一元和二元 仿函数,若以功能划分,可分为算术运算(Arithmetic)、关系运算(Rational)、 逻辑运算(Logical)三大类。任何应用程序欲使用S T L 内建的仿函数,都必须含入 <functional>头文件, S G I 则将它们实际定义于<stl_function.h > 文件中。以下分别描述。

7.2 可 配 接 (Adaptable ) 的关键

  • 在 S T L 六大组件中,仿函数可说是体积最小、观念最简单、实现最容易的一个但是小兵也能立大功—— 它扮演一种"策略”2角色,可以让S T L 算法有更灵活的演出。而更加灵活的关键,在于S T L 仿函数的可配接性(adaptability)。
  • 是的, S T L 仿函数应该有能力被函数配接器(function adapter,第 8 章)修饰,彼此像积木一样地串接• 为了拥有配接能力,每一个仿函数必须定义自己的相应型别(associative types), 就像迭代器如果要融入整个S T L 大家庭,也必须依照 规定定义自己的5 个相应型别一样。这些相应型别是为了让配接器能够取出,获得仿函数的某些信息。相应型别都只是一些 typedef, 所有必要操作在编译期就全部 完成了,对程序的执行效率没有任何影响,不带来任何额外负担0

7.2.1 unary_function

  • unary_function用来呈现一元函数的参数型别和回返值型别。其定义非常简单:

 7.2.2 bin ary—function

  • binary_function用来呈现二元函数的第一参数型别、第二参数型别,以及 回返值型别。其定义非常简单:

 7.3 算术类 (Arithmetic ) 仿函数

  • STL内建的“算术类仿函数”,支持加法、减法、乘法、除法、模数(余数,modulus)和否定(negation)运算。除了 “否定”运算为一元运算,其它都是二 元运算。

 

  •  一般而言不会有人在这么单纯的情况下运用这些功能极其简单的仿函数。仿函
    数的主要用途是为了搭配STL算法。例如以下式子表示要以递增次序对vector iv进行排序:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <set>
#include <vector>
#include <functional>int main(int argc,char* argv[]){std::equal_to<int>equal_to_obj{};std::not_equal_to<int>not_equal_to_obj{};std::greater<int>greater_obj{};std::greater_equal<int>greater_equal_obj{};std::less<int>less_obj{};std::less_equal<int>less_equal_obj{};//调用 创建的对象 旅行函数的功能std::cout << equal_to_obj(3,5) << std::endl;      //0std::cout << not_equal_to_obj(3,5) << std::endl;  //1std::cout << greater_obj(3,5) << std::endl;       //0std::cout << greater_equal_obj(3,5) << std::endl; //0std::cout << less_obj(3,5) << std::endl;          //1std::cout << less_equal_obj(3,5) << std::endl;    //1// 以下直接以仿函数的临时对象履行函数功能// 语法分析:functor<T>()是一个临时对象,后面再接一对小括号// 意指调用 function call operatorstd::cout << std::equal_to<int>()(3,5) << std::endl;std::cout << std::not_equal_to<int>()(3,5) << std::endl;std::cout << std::greater_equal<int>()(3,5) << std::endl;std::cout << std::greater_equal<int>()(3,5) << std::endl;std::cout << std::less<int>()(3,5) << std::endl;std::cout << std::less_equal<int>()(3,5) << std::endl;return 0;
}

 7.5 逻 辑 运 算 类 (Logical)仿函数

#include <iostream>
#include <algorithm>
#include <iterator>
#include <set>
#include <vector>
#include <functional>int main(int argc,char* argv[]){std::logical_and<int>and_obj{};std::logical_or<int>or_obj{};std::logical_not<int>not_obj{};// 以下运用上述对象,履行函数功能std::cout << and_obj(true, true) << std::endl;std::cout << or_obj(true, false)<< std::endl;std::cout << not_obj(true) << std::endl;// 以下直接以仿函数的临时对象履行函数功能// 语法分析: functor<T>() 是一个临时对象,后面再接一对小括号// 意指调用 function call operatorstd::cout <<  << std::endl;std::cout <<  << std::endl;std::cout <<  << std::endl;return 0;
}

 7 .6 证同 ( id en tity ) 、 选 择 (se le c t) 、 投 射 (project)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446426.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习6 字典基础知识和常用函数

字典概念 字典是 Python 提供的一种常用的数据结构&#xff0c;它用于存放具有映射关系的数据。为了保存具有映射关系的数据&#xff0c;Python 提供了字典&#xff0c;字典相当于保存了两组数据&#xff0c;其中一组数据是关键数据&#xff0c;被称为 key&#xff1b;另一组数…

Java web后端2 Servlet Maven HttpServlet ServletConfig ServletContext HTTP协议

创建项目 新建项目 Java Enterprise JDK1.8 Web Application Tomcat JAVA 默认 过程需要联网 Maven的配置 IDEA内置Maven 修改本地仓库位置&#xff0c;因为以后会越来越大 替换配置文件&#xff1a; 阿里云镜像下载 Servlet基础 1.动态Web资源开发 2.Servlet是使用J…

STL源码剖析 配接器

配接器(adapters)在 STL组件的灵活组合运用功能上&#xff0c;扮演着轴承、转换器的角色。Adapter这个概念&#xff0c;事实上是一种设计模式(design pattern)。 Design Patterns)) 一书提到23个最普及的设计模式&#xff0c;其中对odopter样式的定义如下&#xff1a;将 一个cl…

中科大 计算机网络3 网络边缘Edge

网络结构 边缘系统 网络核心 接入网 方块&#xff1a;边缘系统(主机) 圆的&#xff1a;网络核心&#xff0c;数据交换作用 连接边缘系统和网络核心的叫做接入网&#xff08;access&#xff09;&#xff0c;把边缘的主机接入到网络核心&#xff08;所以是分布式的&#xff09; …

STL源码剖析 入门开始 STL概论与版本简介

源代码之中时而会出现一些全局函数调用操作&#xff0c;尤其是定义于<stl_construct.h> 之中用于对象构造与析构的基本函数&#xff0c;以及定义于<stl_uninitialized.h>之 中 用 于 内 存 管 理 的 基 本 函 数 &#xff0c; 以及定义于<stl_algobase.h>之中…

中科大 计算机网络4 网络核心Core 分组交换 电路交换

网络核心 电路交换&#xff08;线路交换&#xff09;&#xff1a;打电话之前&#xff0c;先建立一条链路&#xff08;物理&#xff09; 分组交换&#xff1a;存储转发的方式 电路交换&#xff08;线路交换&#xff09; 通过信令&#xff08;控制信息&#xff0c;如&#xf…

STL 源码剖析 空间配置器

以STL的运用角度而言&#xff0c;空间配置器是最不需要介绍的东西&#xff0c;它总是隐藏在一切组件&#xff08;更具体地说是指容器&#xff0c;container&#xff09; 的背后但是STL的操作对象都存放在容器的内部&#xff0c;容器离不开内存空间的分配为什么不说allocator是内…

中科大 计算机网络7 分组延迟 分组丢失 吞吐量

分组丢失和延迟的原因 队列太长没有意义&#xff0c;用户需求 排队&#xff1a;输出能力<到来的分组&#xff0c;需要等待 四种分组延迟 节点处理延迟&#xff1a;确定的 排队延迟&#xff1a;随机&#xff0c;取决于网络情况 一个比特的传输时间&#xff1a; R1Mbps …

STL源码剖析 迭代器iterator的概念 和 traits编程技法

iterator模式定义如下&#xff1a;提供一种方法&#xff0c;使之能够依序巡访某个 聚合物(容器)所含的各个元素&#xff0c;而又无需暴露该聚合物的内部表述方式.STL的中心思想在于&#xff1a;将数据容器(containers)和算法(algorithms)分开&#xff0c;彼此独立设计&#xff…

中科大 计算机网络11 应用层原理

应用层大纲 传输层向应用层提供的服务&#xff0c;形式是Socket API&#xff08;原语&#xff09; 一些网络应用的例子 互联网层次中&#xff0c;应用层协议最多 流媒体应用&#xff1a;直播 网络核心最高的层次就是网络层 应用进程通信方式 C/S&#xff1a; 客户端&…

STL源码剖析 序列式容器 vector 和 ilist

Vector list 单向链表 ilistlist的删除操作&#xff0c;也只有指向被删除元素的迭代器会失效&#xff0c;其他迭代器不会受到影响

中科大 计算机网络5 接入网和物理媒体

接入网 接入网&#xff1a;把边缘&#xff08;主机&#xff09;接入核心&#xff08;路由器&#xff0c;交换机&#xff09; 骨干网【连接主机和主机】和接入网中都有物理媒体 接入方式&#xff1a;有线和无线 带宽共享/独享 接入网&#xff1a;住宅接入modem modem调制解调…

STL源码剖析 序列式容器 deque双端队列

相较于vector的内存拷贝&#xff0c;deque在内存不足时只需要进行内存的拼接操作即可&#xff0c;不需要重新配置、复制、释放等操作&#xff0c;代价就是迭代器的架构不是一个普通的指针&#xff0c;比较复杂d e q u e 的迭代器 deque是分段连续空间。维持其“整体连续”假象…

中科大 计算机网络6 Internet结构和ISP

互联网的结构 端系统通过接入ISPs接入互联网 n个ISP互相连接&#xff1a; IXP,Internet exchage point:互联网接入点&#xff0c;互联网交互点 ISP&#xff1a;互联网服务提供商&#xff0c;提供接入&#xff0c;提供网络【中国移动&#xff0c;中国电信】 ICP&#xff1a…

STL源码剖析 Stack栈 queue队列

随机迭代器用于随机数据访问&#xff0c;所以栈stack不具备此功能

中科大 计算机网络8 协议层次和服务模型

协议层次 协议层次&#xff1a;现实生活中的例子 分层 分层处理和实现复杂系统 图中&#xff0c;左边是模块&#xff0c;右边是分层 计算机的设计是分层&#xff0c;每一层实现一个或一组功能&#xff0c;下层向上层提供服务&#xff1b;但效率比较低 对等层实体通过协议来交换…

STL源码剖析 heap堆结构

heap一般特指max-heap&#xff0c;即最大的元素位于heap和array的首部 heap不提供遍历功能&#xff0c;也不提供迭代功能

中科大 计算机网络9 互联网历史

总纲 计算机网络 早期1960以前 1961-1972 NCP协议&#xff1a;相当于现在的TCP和IP协议 每个节点即是数据的源也是数据的目标

STL源码剖析 序列式容器 slist

STL l i s t 是个双向链表(double linked lis t) 。SGI STL提供了一个单向链 表 (single linked lis t) , 名 为 slist s l i s t 和 l i s t 的主要差别在于&#xff0c;前者的迭代器属于单向的Forwardlterotor, 后者的迭代器属于双向的Bidirectional Iterator.为此&#xff0…