【STL源码剖析】总结笔记(12):仿函数(Functors)与适配器(Adapter)

00 写在前面

仿函数(functors)和适配器(adapter)就到了整个STL的最后部分。虽然这两部分内容不是很多,可以放在一起说。

但作为STL六大部件中的两大部件,这两者还是有很多设计的精华在里面,值得我们学习。

这也是【STL源码剖析】总结笔记的最后一篇。

01 仿函数(Functors)


仿函数的由来

仿函数,顾名思义,就是类似函数的一种东西。在讨论仿函数之前,我们来看看它是如何产生的。

在前面我们见识了很多算法,算法大都提供一个默认版本,但如果用户想根据不同的应用场景对算法进行变换,也是可以的。比如sort排序算法默认是升序的,我们还可以根据操作的不同变为降序等等。

而这里的”操作“就是改变算法的关键。

首先第一种方法是把这个操作写成一个函数,然后在算法的参数中传入函数指针。这样是完全可以实现对算法的改变的,但是会有一个问题,就是不够灵活,不能随意改变。

举个例子,求数组中大于10的数的个数。

int RecallFunc(int *start, int *end, bool (*pf)(int)) { 
    int count=0; 
    for(int *i=start;i!=end+1;i++) { 
        count = pf(*i) ? count+1 : count; 
    } 
    return count; 
} 

bool IsGreaterThanTen(int num) { 
    return num>10 ? true : false; 
} 

int main() { 
    int a[5] = {10,100,11,5,19}; 
    int result = RecallFunc(a,a+4,IsGreaterThanTen);
    return 0;
}

我们可以把大于10写为一个函数,再传入原本的算法中。

但如果我们想实现大于任何数,让IsGreaterThanTen(int num)变为IsGreaterThan(int num1,int num2)传入两个参数,那就不可以实现了。(当然定义为全局变量也可以实现)

这时候仿函数就派上用场了。

再举个例子,比如常见的比较大小用的less

template <class T>
struct less:public binary_function<T,T,bool>{
    bool operator()(const T&x,const T&y)const{turn x<y};
};

这样定义之后就可以产生一个仿函数对象了。

可以产生仿函数实体,然后调用实体:

less<int> less_obj;
less_obj(3,5);

或者使用临时对象**(常用)**

less<int>()(3,5);

当然,配合算法才是仿函数的目的,只为算法服务。

sort(vi.begin(),vi.end(),less<int>());

### 仿函数与算法

大家可能也注意到了,仿函数需要重载小括号。

而这样的重载可以使其很好地融合于算法之中。

比如算法accumulate,在第二个版本中注意第三个参数

template <class InputIterator,class T,class BinaryOperation>
T accumulate(InputIterator first,InputIterator last,T init,BinaryOperation binary_op){
    for(;first!=last
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值