C++STL标准库学习笔记函数对象
Posted AwakeFantasy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++STL标准库学习笔记函数对象相关的知识,希望对你有一定的参考价值。
前言:
在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标记了出来。
在这一篇文章中,我们主要对STL中的函数对象进行简单的介绍。
正文:
1. 函数对象
若一个类重载了运算符“()”,则该类的对象就成为函数对象
例1:
#include<iostream> using namespace std; class CMyAverage //函数对象类 public: double operator()(int a1,int a2,int a3) return (double)(a1+a2+a3)/3; ; int main(int argc, char const *argv[]) CMyAverage average;//函数对象 cout<<average(3,2,3);//等价于average.operator()(3,2,3) //输出:2.66667 return 0;
例2:
#include<iostream> #include<vector> #include<algorithm> #include<numeric> #include<functional> using namespace std; int sumSquares(int total, int value) return total + value*value; template<class T> void PrintInterval(T first, T last) //输出区间[first, last)中的元素 for (; first != last; ++first) cout<<*first<<" "; cout<<endl; template<class T> class SumPowers private: int power; public: SumPowers(int p):power(p) const T operator()(const T & total, const T & value) //计算value的power次方,加到total上 T v = value; for (int i = 0; i < power-1; i++) v = v * value; return total + v; ; int main(int argc, char const *argv[]) const int SIZE = 10; int a1[] = 1,2,3,4,5,6,7,8,9,10; vector<int> v(a1,a1+SIZE); cout<<"1)"; PrintInterval(v.begin(),v.end()); int result = accumulate(v.begin(),v.end(),0,sumSquares); //求出v上面所有元素的平方和 cout<<"2)平方和"<<result<<endl; result = accumulate(v.begin(),v.end(),0,SumPowers<int>(3)); //SumPowers<int>(3)中,这是一个对象,其中power = 3 //求出v上面所有元素的立方和 cout<<"3)立方和"<<result<<endl; result = accumulate(v.begin(),v.end(),0,SumPowers<int>(4)); cout<<"4)4次方和"<<result<<endl; return 0; /* 输出: 1)1 2 3 4 5 6 7 8 9 10 2)平方和385 3)立方和3025 4)4次方和25333 */
其中:
在int result = accumulate(v.begin(),v.end(),0,SumSquares)
这段代码中,实例化出:
int accumlate(vector<int>::iterator first, vector<int>::iterator last, int init, int(*op)(int,int)) for (; first != last; ++first) init = op(init,*first); return init;
而在accumulate(v.begin(),v.end(),0,SumPowers<int>(3));
实例化出:
int accumlate(vector<int>::iterator first, vector<int>::iterator last, int init, SumPowers<int>op) for (; first != last; ++first) init = op(init,*first); return init;
函数对象的价值:
在刚刚的例子中,假使我们要求一个数组的1,2,3,4,5,6,7,8,9....次方和,如果不使用函数对象的话,就要可能要写n多个函数(虽然老师是这样说的,但是我传进去一个参数来知道做几次方不好吗,不过从这个例子中看,accumulate支持的函数似乎只支持两个参数传入,一个init,一个value,这种情况看来还是得用函数对象)
2. STL中的函数对象类模板
以下模板可以用来生成函数对象。
equal_to
greater
less
......
它们都是模板而且也实现了“()”这个成员函数
都在头文件:<functional>里定义了
如:
template<class T> struct greater:public binary function<T,T,bool> bool operator()(const T&x,const T&y)const return x > y; ;
3. greater的应用
list有两个sort成员函数
void sort();
将list中的元素按“<”规定的比较方法升序排列。
template<class Compare>
void sort(Compare op)
将list中的元素按op规定的比较方法升序排序。即要比较x,y大小时,看op(x,y)的返回值,为true则认为x小于y
样例:
#include<list> #include<iostream> using namespace std; class myless public: bool operator()(const int & c1, const int & c2) return (c1 % 10)<(c2 % 10);//比较个位数大小 ; template<class T> void Print(T first, T last) for (; first != last; ++first) cout<<*first<<","; int main(int argc, char const *argv[]) const int SIZE = 5; int a[SIZE] = 5,21,14,2,3; list<int> lst(a,a+SIZE); lst.sort(myless()); Print(lst.begin(),lst.end()); cout<<endl;//输出:21,2,3,14,5, lst.sort(greater<int>());//greater<int>()是个对象 Print(lst.begin(),lst.end()); cout<<endl;//输出:21,14,5,3,2, return 0;
这个没有什么特别需要强调的。
4. 在STL中使用自定义的“大”“小”关系
关联容器和STL中许多算法,都是可以用函数或函数对象自定义比较器的。在自定义了比较器op的情况下,以下三种说法是等价的:
1)x小于y
2)op(x,y)返回值为true
3)y大于x
5. 例题:写出MyMax模板
#include<iostream> #include<iterator> using namespace std; class MyLess public: bool operator()(int a1, int a2) if((a1%10)<(a2%10)) return true; else return false; ; bool Mycompare(int a1, int a2) if((a1%10)<(a2%10)) return false; else return true; template<class T, class Pred> T MyMax(T first, T last, Pred myless) T tmpMax = first; for (; first != last; ++first) if (myless(*tmpMax, *first)) tmpMax = first; return tmpMax; int main(int argc, char const *argv[]) int a[] = 35,7,13,19,12; cout<<*MyMax(a,a+5,MyLess())<<endl;//输出:19 cout<<*MyMax(a,a+5,Mycompare)<<endl;//输出:12 return 0;
后记:
到了这一节就感觉内容抽象了许多,但是c++对这些东西(指函数里面套函数)的支持还是让人感觉很惊喜的。
以上是关于C++STL标准库学习笔记函数对象的主要内容,如果未能解决你的问题,请参考以下文章
STL标准库 & 范型编程学习笔记:OOP(面向对象编程)与 GP(范型编程)容器之间的实现与分类