关于仿函数很多博客上都有,形式很简单,用途也很多。
一句话总结:重载了()运算符的类可以称之为仿函数functor
现在写一个“比较”

class MyLess{
public:bool operator()(int a, int b){return a < b;}
}; 

大多数人会这样写,其实这样写没有错,而且基本所有算法都可以通过
比如:

class MyLess{
public:bool operator()(int a, int b){return a < b;}
};
class Less10{
public:bool operator()(int a){return a < 10 ? true : false;}
};
int main() {vector<int> v{1, 40, 5, 60, 5, 6};cout<<count_if(v.begin(), v.end(), Less10())<<endl;sort(v.begin(), v.end(), MyLess());for(auto i : v)cout<<i<<" ";cout<<endl;
}

上面两个仿函数MyLess、Less10。两个算法count_if、sort。
这样的仿函数基本上可以用stl中所有的算法。
看看STL中less怎么写的吧

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

除了模板,还有就是less继承了个binary_function,这个是什么鬼?
为什么要继承它?继承它有啥用?
看一个例子:

class MyLess{
public:bool operator()(int a, int b){return a < b;}
};
int main() {vector<int> v{1, 40, 5, 60, 5, 6};cout<<count_if(v.begin(), v.end(), bind2nd(less<int>(), 50))<<endl;
}

bind2nd这个叫绑定器,可以绑定一个仿函数的第二个参数。
为啥要使用绑定器?看看第段代码,有没有发现我统计数组中小于10的元素个数太单一了?一点都没有可扩展性,当我们要小于50的时候又得再写一个仿函数,太累了。所以绑定器产生了,现在C++11的绑定都是用bind这个函数(这个函数太厉害了,比bind1nd,bind2nd强大的多,有机会可以去了解下)
回到正题,如果我们把less()换成我们自己写的仿函数,编译就有问题,为啥呢?抛开模板,就是没有继承那个什么鬼了。
看看那个鬼张啥样吧

template <class Arg1, class Arg2, class Result>
struct binary_function {typedef Arg1 first_argument_type;typedef Arg2 second_argument_type;typedef Result result_type;
};      

啥?一个成员都木有啊。
其实看STL最大的收获是懂得了typedef的使用,别看简单的一个typedef,几乎在stl中无处不在,绑定器,适配器,萃取器等等,都和typedef密不可分,但是我们正真写程序用typedef的又有几个。
回到正题,我们在看看bind2nd

template <class Operation, class T>
inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {typedef typename Operation::second_argument_type arg2_type;return binder2nd<Operation>(op, arg2_type(x));
}

原来bind2nd要用typedef得到第二参数的类型啊,有啥用?为了检查第二参数是否类型正确,如果转换不了那就直接出错
so,结果就出来了,为啥要继承那个鬼。
再继续看看binder2nd吧

template <class Operation>
class binder2nd: public unary_function<typename Operation::first_argument_type,typename Operation::result_type> {
protected:Operation op;typename Operation::second_argument_type value;
public:binder2nd(const Operation& x,const typename Operation::second_argument_type& y) : op(x), value(y) {}result_type operator()(const argument_type& x) const {return op(x, value); }
};

这里也需要知道参数类型和返回类型,而且binder2nd本身也是一个仿函数,而且继承了unary_function类

template <class Arg, class Result>
struct unary_function {typedef Arg argument_type;typedef Result result_type;
};

到此为止我们可以总结了

仿函数如果要融入STL那么需要继承一个类
一个参数用unary_function
两个参数用binary_function

注意:为啥binary_function有两个参数还是继承unary_function呢?
因为binary_function需要别人推导的只有第一参数而已,第二参数类型已经确定,在本类中已经typedef了

C++如何写adaptable仿函数相关推荐

  1. C++的几种遍历形式

    引言 看到了STL中的for_each遍历算法,看完后第一感觉就是for_each能做的用for循环也照样可以啊,于是归类了几种遍历形式,在这里总结一下: 在这里说一下为什么C++中有这么多种的遍历形 ...

  2. 内建函数对象(STL)

    引言 函数对象是重载函数调用操作符的类,函数对象使用重载的()时,因为类似函数调用,也叫仿函数 所以仿函数(函数对象)就是一个类 我们可以自己建立函数对象,这里就不具体说了:STL中同样给我们提供了一 ...

  3. C++11 lambda表达式、function类模板、bind函数适配器

    文章目录 lambda表达式 lambda表达式的语法 lambda表达式的原理 function模板 function与重载函数 bind函数适配器 lambda表达式 当我们在写代码的时候如果经常 ...

  4. C++STL之优先队列

    首先先讲一下仿函数 仿函数 仿函数(functor),就是使一个类的使用看上去像一个函数.其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了.仿函数的主要功能是 ...

  5. Boost搜索引擎项目

    目录 1.项目相关背景 2.搜索引擎的相关宏观原理 3.搜索引擎技术栈和项目环境 4.正排索引 && 倒排索引--搜索引擎原理 5.编写数据去标签与数据清洗的模块 -- parser. ...

  6. C++11特性(详细版)

    C11 1.C11优势 2.列表初始化 3.变量类型推导 1.为什么需要类型推导 2.decltype类型推导(了解) 为什么需要decltype decltype 4.final 与 overrid ...

  7. C++11主要新增使用语法介绍

    目录 1. C++11简介 2. 统一的列表初始化 2.1 {}初始化 2.2 std::initializer_list 3. 声明 3.1 auto 3.2 decltype 3.3 nullpt ...

  8. C++标准库分析总结(一)——<标准库简介>

    目录 1 你应该具备的基础 1.1 你应该具备的基础 1.2 我们的目标 2 标准库介绍 2.1 C++标准库与C++标准模板库二者关系及表现形式 2.2 STL六大部件 2.3 STL的简单使用 2 ...

  9. Th2.8:vector类型详述

    本博客将记录:vector类型这个知识点的笔记!     今天总结的知识分为3个点:    一.vector类型简介    二.定义和初始化vector对象(只介绍日常coding中最常用的几种)   ...

  10. 关联式容器---map和set

    map和set 1 关联式容器 2 键值对 3 树型结构的关联式容器 3.1 set 3.1.1 set 的介绍 3.1.1 set 的使用 3.2 map 3.2.1 map的介绍 3.2.2 ma ...

最新文章

  1. 习惯几乎可以绑住一切,只是不能绑住偶然。比如那只偶然尝了鲜血的老虎。...
  2. webhook简单部署
  3. 老男孩Python全栈开发(92天全)视频教程 自学笔记20
  4. CodeForces-589B(思维/排序)
  5. linux mysql 忘记root密码_Linux MySQL忘记root密码解决方案
  6. JCP执行委员会新成员选举结果揭晓:Hologic未获通过
  7. (三)C语言之九条语句
  8. 好用的import: Vite的Glob 导入
  9. 【进阶版】 机器学习之强化学习、蒙特卡罗、AlphaGo原理浅析(22)
  10. 阿里代码规范检查工具的安装使用以及阿里代码格式化
  11. 解决IDEA导入项目后无法运行的问题
  12. 初中计算机教案ps,初中信息技术《认识Photoshop CS2的工作界面》教案
  13. 工程制图与AUTOCAD【1】
  14. NSUOJ2888最小唯一表示前缀(偷懒的xzj)
  15. linux虚拟机释放内存cache
  16. JDK源码解析---Short
  17. 偏差(bias)和方差(variance)及其与K折交叉验证的关系
  18. 有没有人被向量空间、内积空间、欧式空间、希尔伯特空间、巴拿赫空间概念折磨的?
  19. 小程序登录问题--登录函数getUserInfo()写在app.js中,首次加载无法获取后台处理过的用户的信息,刷新一次后就可以获取的解决
  20. 习题 6.10 有一篇文章,共有三行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其他字符的个数。

热门文章

  1. mysql number 类型_mysql number类型
  2. 舱机器人尾巴毛茸茸_『新奇玩意』毛茸茸的机器人不仅可撸,还会摇尾巴
  3. cad图层置顶的lisp_cad中的底图老置顶,如何让它永久置底?
  4. 读书笔记:时间与精力管理:拖延症与六种效应
  5. 《三体》读后思考-泰勒展开/维度打击/黑暗森林
  6. elasticsearch启动报错:master not discovered yet
  7. 考勤系统(打卡时间计算)
  8. 【杂七杂八】虚拟机win中 腾讯会议视频黑屏
  9. 虚拟机安装win7出现错误
  10. 推荐一个统计英语词频的软件:replace pioneer