STL学习笔记(仿函数)

仿函数(Functors)

仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。

例如我们定义一个类:

class X{public:return-value operator()(arguments) const;...  
};

然后就可以把这个类别的对象当做函数调用

X fo;
...
fo(arg1,arg2)  //等价于fo.operator()(arg1,arg2);

 显然,这种定义形式更为复杂,却又三大妙处:

1.仿函数比一般函数更灵巧,因为它可以拥有状态。

2.每个仿函数都有其型别。因此可以将仿函数的型别当做template参数传递。

3.执行速度上,仿函数通常比函数指针更快。

 

 

仿函数可当做排序准则

 1 #include <iostream>
 2 #include <string>
 3 #include <set>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 class Person{
 8     public:
 9         string firstname() const;
10         string lastname() const;
11         ...        
12 };
13 
14 class PersonSortCriterion{
15     public:
16         bool operator()(const Person&p1,const Person& p2) const {
17             return p1.lastname()<p2.lastname()||
18                     (!(p2.lastname()<p1.lastname())&&
19                     p1.firstname()<p2.firstname());
20         }
21 };
22 
23 int main()
24 {
25     typedef set<Person,PersonSortCriterion> PersonSet;
26     PersonSet coll;
27     PersonSet::iterator pos;
28     for(pos=coll.begin();pos!=coll.end();++pos){
29         ...
30     }
31     ...
32 }
View Code

这里的coll适用了特殊排序准则PersonSortCritersion,而它是一个仿函数类别。所以可以当做set的template参数,而一般函数则无法做到这一点。

 

拥有内部状态的仿函数

下面例子展示仿函数如何模拟函数在同一时刻下拥有多个状态

 1 #include <iostream>
 2 #include <list>
 3 #include <algorithm>
 4 #include "print.cpp"
 5 using namespace std;
 6 
 7 class IntSequence
 8 {
 9 private:
10     int value;
11 public:
12     IntSequence(int initialValue):value(initialValue){}
13     int operator() ()
14     {
15         return value++;
16     }
17 };
18 
19 int main()
20 {
21     list<int> coll;
22     generate_n(back_inserter(coll),9,IntSequence(1));
23     PRINT_ELEMENTS(coll);
24     generate(++coll.begin(),--coll.end(),IntSequence(42));
25     PRINT_ELEMENTS(coll);
26 }
View Code

 

for_each()的返回值

使用for_each()可以返回其仿函数。下面将演示这一点

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 class MeanValue
 7 {
 8 private:
 9     long num;
10     long sum;
11 public:
12     MeanValue():num(0),sum(0){}
13     void operator() (int elem)
14     {
15         num++;
16         sum+=elem;
17     }
18     double value()
19     {
20         return static_cast<double>(sum)/static_cast<double>(num);
21     }
22 };
23 
24 int main()
25 {
26     vector<int> coll;
27     for(int i=1;i<=8;++i)
28     {
29         coll.push_back(i);
30     }
31     MeanValue mv=for_each(coll.begin(),coll.end(),MeanValue());
32     cout<<"mean value:"<<mv.value()<<endl;
33 }
View Code

 

预定义的仿函数

C++标准程序库提供了许多预定义的仿函数。下面列出了所有这些仿函数

对对象排序或进行比较时,一般都以less<>为预设排序准则。要使用这些仿函数,必须包含头文件<functional>。

 

 

函数配接器(Function Adapters)

所谓“函数配接器”是指能够将仿函数和另一个仿函数(或某个值,或一般函数)结合起来的仿函数。函数配接器也声明与<functional>中。

例如以下语句:

find_if(coll.begin(),coll.end(),bind2nd(greater<int>()),42)

其中bind2nd是将一个二元仿函数(greater<>)转换成一元仿函数。它通常将第二参数传给“由第一参数指出”的二元仿函数,作为后者的第二参数。

下面列出了预定义的函数配接器

 

转载于:https://www.cnblogs.com/runnyu/p/4840489.html

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

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

相关文章

郸城二高2021年高考成绩查询时间,河南高考最高分是谁,2021年河南高考状元名单分数学校...

每年的高考状元是广大考生、家长以及老师最关注的事情&#xff0c;2021年河南高考状元是谁&#xff0c;以下是小编整理的历年河南高考状元&#xff0c;仅供参考。一、2021年河南高考状元名单2021年河南高考状元暂未公布&#xff0c;小编会持续关注并及时更新。二、2020年河南高…

使用NuGet发布自己的类库包(Library Package)

http://www.cnblogs.com/daxnet/archive/2013/05/07/3064577.html 转载于:https://www.cnblogs.com/shiningrise/p/4842367.html

减少GC开销的5个编码技巧

在这篇文章中&#xff0c;我们来了解一下让代码变得高效的五种技巧&#xff0c;这些技巧可以使我们的垃圾收集器&#xff08;GC&#xff09;在分配内存以及释放内存上面&#xff0c;占用更少的CPU时间&#xff0c;减少GC的开销。当内存被回收的时候&#xff0c;GC处理很长时间经…

HTML5DOM红蓝盒子,DOM介绍以及使用方法(示例代码)

DOM的基本讲解一、DOM(Document Object Model)文档对象模型1、有属性有方法1 var person {2 name:‘派大星‘,3 fav:function(){4 }5 }2、js中对象分类三种(1)用户定义对象(2)内建对象 Array Date Math (内置)(3)宿主对象3、Model Map(地图)(1)把 DOM 看做一颗“树”(2)DOM 把文…

JavaBean为什么要实现Serializable接口

Java"对象序列化"&#xff1a;是指将实现了Serializable接口的对象转换成一组byte&#xff0c;日后要用这个对象时候&#xff0c;可以根据byte数据恢复出来&#xff0c;并据此重新构建那个对象。 优点&#xff1a; 1、JavaBean类基本都要求实现了Serializable接口&…

html的post和get请求参数,HTTP 方法:GET 对比 POST | w3cschool菜鸟教程

HTTP 方法&#xff1a;GET 对比 POST两种最常用的 HTTP 方法是&#xff1a;GET 和 POST。什么是 HTTP &#xff1f;超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信。HTTP 的工作方式是客户端与服务器之间的请求-应答协议。web 浏览器可能是客户端&#xff0c;而…

scrollview 与 listView 的显示不全问题

使用两个GridView&#xff0c;两个GridView一起上下滚动&#xff1b;如果直接将两个GridView添加到同一个界面上&#xff0c;它们是各自滚动的。因此&#xff0c;我考虑使用SrollView&#xff0c;将它们包装一下&#xff01;但这样做会提示如下信息&#xff1a;The vertically …

Java编程中的基本概念

1.Java的JVM内部统一使用的字符表示是Unicode编码&#xff08;不选用任何特定的编码&#xff0c;直接使用它们在字符街中的编号&#xff0c;这是统一的唯一的方法&#xff09;。 2.在JVM加载类的时候&#xff0c;需要经过三个步骤&#xff1a;装载&#xff0c;连接&#xff0c…

怀化学院计算机科学专业排名,2019怀化学院专业排名

怀化学院创办于1958年&#xff0c;前身为怀化师范高等专科学校&#xff0c;2002年经国家教育部批准升格为全日制普通本科院校。不知道选择什么专业好的同学可以根据自己的学习成绩、兴趣爱好来选择自己喜欢的专业。下面是学习啦小编给大家带来的怀化学院专业排名&#xff0c;供…

C++中的也能使用正则表达式

正则表达式Regex(regular expression)是一种强大的描述字符序列的工具。在许多语言中都存在着正则表达式&#xff0c;C11中也将正则表达式纳入了新标准的一部分&#xff0c;不仅如此&#xff0c;它还支持了6种不同的正则表达式的语法&#xff0c;分别是&#xff1a;ECMASCRIPT、…

html文件设置ftp6,vsftp的安装与配置

环境mint17.21.安装dpkg -l|grep ftpsudo apt-get install vsftpd2.去根目录创建一个文件上传的文件夹sudo mkdir /ftpfile3.创建一个用户&#xff0c;他只对上传文件有权限&#xff0c;对系统登录无权限sudo useradd ftpuser -d /ftpfile/ -s /bin/bash4.用chown修改ftpfile的…

筛选法求1到100以内的素数

问题描述&#xff1a; 所谓“筛选法”指的是“埃拉托色尼(Eratosthenes)筛法”。他是古希腊的著名数学家。他采取的方法是&#xff0c;在一张纸上写上1到100全部整数&#xff0c;然后逐个判断它们是否是素数&#xff0c;找出一个非素数&#xff0c;就把它挖掉&#xff0c;最后剩…

Java基础知识强化之集合框架笔记27:ArrayList集合练习之去除ArrayList集合中的重复字符串元素...

1. 去除ArrayList集合中的重复字符串元素&#xff08;字符串内容相同&#xff09; 分析&#xff1a; &#xff08;1&#xff09;创建集合对象 &#xff08;2&#xff09;添加多个字符串元素&#xff08;包含重复的&#xff09; &#xff08;3&#xff09;创建新的集合 &#xf…