【《STL源码剖析》提炼总结】 第7节:仿函数

一.仿函数介绍

1.什么是仿函数

​ 仿函数(functor)在后面的正式命名为 函数对象(function objection),前者的意思是行为像函数的对象,后者更是直接指名其本质是一个对象,行为像是函数。

​ 一般的函数操作即 函数名 + ( + 参数 + ) 调用,为了实现相同的语法,仿函数重载了operator()运算符,因此也可以使用实例 + ( + 参数 + ) 的语法将其像是函数一样使用。

​ 定义的例子

class functor
{
    returnValue operator()( 参数 )
    {
        // code
    }
}

​ 仿函数实际上是对使用者关系比较大的一个类型,比如在使用unordered_map且对应数据是自定义类型(或者是pair)的时候,需要自己手写hash仿函数来作为参数传入。因此侯捷老师说的“对STL库作出扩充”,第一步往往是发生在添加仿函数上。

2.仿函数和函数的区别

​ 既然已经有函数了,可以使用函数指针,那为什么要要有仿函数呢?

  • 函数指针不能满足STL对于抽象性的要求,也不能与其他组间(比如适配器adapter搭配)----即不能提供接口(关于其不可适配的问题将在第二节介绍)
  • 仿函数内部可以定义一些值作为隐性的参数,这是函数指针做不到的,通过搭配额外的数据有更灵活的效果

3.仿函数的用法

  • 构建一个仿函数的实例,然后在实例后加括号来使用
  • 或者直接使用对象名+() 构建临时对象,这个在进行传参的时候经常采用这个做法,比较方便。

4.仿函数的分类

  • 以操作数划分
    • 一元
    • 二元
  • 以功能划分
    • 算数运算
    • 关系运算
    • 逻辑运算

5.仿函数定义的位置

  • 常规调用是使用 <functional> ,(SGI还有一个<ext/functional>,里面有一些非标准的仿函数)
  • 对应的定义位置在<stl_function.h

二.可适配(adaptable)的关键

1.什么是可适配

​ 就像iterator要提供对应的类型作为对外接口一样,仿函数因为使用类嵌套了一层,因此也需要提供类型的接口:参数的类型和返回值的类型。只有这样,在将仿函数传入仿函数适配器的时候,适配器才能正常运作。

2.作为通用接口的两个对象

​ 就像iterator这个通用的类一样,仿函数也要两个提供模板接口的类,只需要对其进行继承即可,就可以定义标准的接口了。

unary_function 一元函数

  • argument_type : 唯一一个参数的类型
  • result_type : 返回值类型

binary_function 二元函数

  • first_argument_type : 第一个参数的类型

  • second_argument : 第二个参数的类型

  • result_type : 返回值类型

    使用实例:

    template <class T>
    struct plus : public binary_function <T,T,T>{
        T operator()(const T&x,const T& y) const {return x + y;}
    }
    

    public binary_function <T,T,T> 便是对应的接口

三.常用仿函数

1.关系运算

​ 其实就是对其运算的调用(因此自定义类可以通过重载运算符)

  • plus 加
  • minus 减
  • multiplies 乘
  • divides 除
  • modulus 取模(%)
  • negate 取否定(加负号)

2.关系运算

​ 同样是关系运算符的调用

仿函数功能
equai_to等于
not_equal_to不等于
greater大于
greater_equal大于等于
less小于
less_equal小于等于

3.逻辑运算

仿函数功能
logical_and逻辑与 &&
logical_or逻辑或 ||
logical_not逻辑非 !

4.证同,选择,投射

​ 这三个不是C++标准库中的内容

类型名称作用
证同identity返回自身
选择select1st取元素的first(常用于pair)
selest2nd取元素的second(常用于pair)
投射project1st传回第一参数,忽略第二参数
project2nd传回第二参数,忽略第一参数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值