仿函数(functors)使用
来源:互联网 发布:windows 10 蓝牙 丢失 编辑:程序博客网 时间:2024/05/17 03:13
我们都知道C++有一个标准库STL,熟练使用STL可以提高我们开发的效率。可能很多人都熟悉诸如vector,list,map等容器,但是作为STL六大组件的仿函数则不太了解,或许有人说,这是个什么东西?学了有什么好处?
仿函数,它行为类似函数,可以作为算法的某种策略,帮助我们更好的使用算法。我们简单看一个例子:
//排序一组数据#include <iostream>#include <vector>#include <algorithm>#include <functional>using namespace std;void PrintV(const vector<int>& v){ int size = v.size(); for (int i = 0; i < size; ++i) { cout << v[i] << " "; } cout << endl;}int main(){ vector<int> v = { 3, 2, 1, 6, 5, 4 }; //默认升序 < sort(v.begin(), v.end()); PrintV(v); // 1 2 3 4 5 6 //降序 > sort(v.begin(), v.end(), greater<int>()); PrintV(v); // 6 5 4 3 2 1 //升序 < sort(v.begin(), v.end(), less<int>()); PrintV(v); // 1 2 3 4 5 6 return 0;}
在上面的例子中,我们想对vector里面数据排序,升序和降序,我们不需要自己写,只需要调用sort,并根据要求传入仿函数以保证升序还是降序,是不是很方便呢?
当然排序这个算法不算难,但是在实际编程用STL,在绝大部分场合下无论是效率还是时间都远比我们自己写一个要快,更可况STL中实现的一个泛型算法,可以针对任意类型排序,而这样就需要我们了解仿函数。
什么是仿函数?所谓仿函数functor,又叫函数对象,它用起来就像函数一样。如果你对某个class进行operator()重载,他就是仿函数。
什么叫用起来像函数?比如:
template<class T>struct Plus{ T operator()(const T& a, const T& b) { return a + b; }};int main(){ Plus<int> f; cout << f(1, 2) << endl;}
在这里面,f看起来就像一个函数一样,实际上只是一个类对象调用operator()而已。它也可以这么写,结果是一样的。
cout << Plus<int>()(1, 2) << endl; //构造一个临时对象Plus<int>(),然后再调用operator()
经过上面的描述,我们知道要想使用仿函数,需要operator()重载,调用时候只需要生成对象x,再调用x()就可以完成我们所需的操作。
在前面,我们讲过STL设计是可以针对任意类型的,因此,我们自己定义的类型也可以被STL兼容。我们还是拿上面的sort为例子,在某些情况,我们可能一个元素有多个参数,但是要根据某个参数来排序,比如学生要根据成绩排名,学生的信息可能是这样的:
class Student{public: Student(string n, int i, double s) : name(n), id(i), score(s) {} double GetScore() const { return score; } string GetName() const { return name; } int GetID() const { return id; }private: string name; int id; double score;};bool Com(const Student& s1, const Student& s2) //升序策略{ return s1.GetScore() < s2.GetScore();}struct Com_D //降序策略{ bool operator()(const Student& s1, const Student& s2) { return s1.GetScore() < s2.GetScore(); }};void display(const Student& x){ cout << x.GetName() << " " << x.GetScore() << endl;}class Display{public: void operator()(const Student &x) { cout << x.GetName() << " " << x.GetScore() << endl; }};int main(){ vector<Student> v; v.push_back(Student("peter", 1, 60.9)); v.push_back(Student("andy", 2, 85.5)); v.push_back(Student("david", 3, 72.9)); v.push_back(Student("john", 4, 33.3)); v.push_back(Student("tom", 5, 92.5)); //按照成绩升序 sort(v.begin(), v.end(), Com); //函数指针 for_each(v.begin(), v.end(), display); //函数指针 cout << endl; //按照成绩降序 sort(v.begin(), v.end(), Com_D()); for_each(v.begin(), v.end(), Display()); return 0;}
注意,函数指针也可以理解为一种仿函数,因此sort(v.begin(), v.end(), Com);中的Com就是一个函数指针,传入给sort,也许有人会问,既然函数指针也能完成这个需求,为什么还要这么烦设计出仿函数,这是因为函数指针不能满足STL对于抽象性的要求,它也无法与STL其他组件搭配,因而必须要有仿函数。
- 仿函数(functors)使用
- 仿函数(functors)
- 仿函数(functors/function objects)原理及使用
- 泛化仿函数(functors)
- 七 仿函数 functors
- 谓词函数predicates和仿函数functors
- C++学习_仿函数(functors)
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- 仿函数使用要领
- 仿函数使用要领
- 仿函数使用要领
- 仿函数使用要领
- 仿函数的使用
- 仿函数使用小结
- NOJ_1014
- autorelease的使用场景
- elasticsearch学习之IK分词器
- MairaDB 函数(三)
- xgboost参数说明,模型训练,模型预测java接口相关说明
- 仿函数(functors)使用
- JavaScript数据类型和转换
- Vim中复制粘贴缩进错乱问题的解决方案
- Block的内存管理以及变量Capture
- Android加载大图片APP
- 泛化、聚合、关联关系以及场景图用例图
- 392. Is Subsequence
- 【BZOJ4813】 [Cqoi2017]小Q的棋盘
- poj 1958 4汉诺塔问题