STL学习之十二:函数对象和谓词

来源:互联网 发布:mac如何更改启动项 编辑:程序博客网 时间:2024/05/22 08:03

本文主要介绍函数对象和谓词的示例代码。函数对象是属于类对象,能突破函数的概念 ,用以保持条用状态信息。具体的使用信息科参见代码中的注释部分。

 示例代码主要包含:

1 .函数对象的定义   函数对象和普通函数的区别;
2. 分清楚STL算法返回的值时迭代器 还是 谓词(函数对象) 是STL算法入门的重要点。

下面是示例代码:

#include "iostream"using namespace std;#include "vector"#include "set"#include "queue"#include "list"#include "algorithm"#include "string"#include "functional"template <typename T>class ShowElement{public:ShowElement(){n = 0;}void operator()(T &t){n++;cout << t <<"  ";}void printN(){cout << "n:" << n << endl;}protected:private:int n;}; // 函数模板 template <typename T>void FuncShowElement1(T &t){cout << t << endl;}// 普通函数void FuncShowElement2(int &t){cout << t << " ";}void main11(){int a =10;ShowElement<int> showElemt;showElemt(a);// 函数对象的执行 很像一个函数==》仿函数FuncShowElement1<int>(a);FuncShowElement2(a);}// 函数对象的好处void main12(){vector<int> v1;v1.push_back(1);v1.push_back(3);v1.push_back(5);for_each(v1.begin(),v1.end(),ShowElement<int>());// 匿名仿函数对象cout << endl;for_each(v1.begin(),v1.end(),FuncShowElement2);// 通过回调函数 谁使用for_each谁去填写回调函数的入口地址ShowElement<int> s2;for_each(v1.begin(),v1.end(),s2);s2.printN();// 结果 n = 0;按说n=3,因为for_each自身的原因:_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)// 最后一个参数不是&_Fn1 _Func,不会改变,但根据for_each的返回值特点(依然是_Fn1类型)可以修改。如下:s2 = for_each(v1.begin(),v1.end(),s2);s2.printN();// 结果n=3            }template <typename T>class IsDiv{public:IsDiv(const T &div){this->div = div;}bool operator()(T &t)//谓词{return (t%div == 0);}protected:private:T div;};void main13(){vector<int> v2;for (int i=10;i<30;i++){v2.push_back(i);}int a=4;IsDiv<int> myDiv(a);vector<int>::iterator it;it = find_if(v2.begin(),v2.end(),IsDiv<int>(a));//因为find_if返回的是一个迭代器,所以要建立一个迭代器来接收if (it == v2.end()){cout << "no" << endl;}else{cout <<"first is :" << *it << endl;}}template <typename T>class SumAdd{public:T operator()(T t1,T t2){return t1 + t2;}protected:private:};// v1 v2 = v3void main14(){vector<int> v1,v2;vector<int> v3;v1.push_back(1);v1.push_back(3);v1.push_back(5);v2.push_back(2);v2.push_back(4);v2.push_back(6);v3.resize(10);transform(v1.begin(),v1.end(),v2.begin(),v3.begin(),SumAdd<int>());for (vector<int>::iterator it=v3.begin();it!=v3.end();it++){cout << *it << " ";}cout << endl;}bool MyCompare(const int &a,const int &b){return a<b;//从小到大排序}void main15(){vector<int> v(10);for (int i=0;i<10;i++){int tmp = rand() %100;v[i] = tmp;}for (vector<int>::iterator it=v.begin();it!=v.end();it++){cout << *it << " ";}cout << endl;for_each(v.begin(),v.end(),FuncShowElement2);cout << endl;sort(v.begin(),v.end(),MyCompare);for_each(v.begin(),v.end(),FuncShowElement2);cout << endl;}// 二元谓词在set中的应用struct CompareNoCase{bool operator()(const string &str1,const string &str2){string str1_,str2_;str1_.resize(str1.size());str2_.resize(str2.size());transform(str1.begin(),str1.end(),str1_.begin(),tolower);transform(str2.begin(),str2.end(),str2_.begin(),tolower);return (str1_ < str2_);// 从小到大排序}};void main16(){set<string> set1;set1.insert("bbb");set1.insert("aaa");set1.insert("ccc");set<string>::iterator it = set1.find("aAa");//find默认情况下是区分大小写的,下面改成不区分if (it == set1.end()){cout << "no" << endl;}else{cout << "找到"<< *it << endl;}//find默认情况下是区分大小写的,下面改成不区分set<string,CompareNoCase> set2;//调用函数set2.insert("bbb");set2.insert("aaa");set2.insert("ccc");set<string,CompareNoCase>::iterator it2 = set2.find("aAa");//调用函数if (it2 == set2.end()){cout << "no" << endl;}else{cout << "找到"<< *it2 << endl;}}void main(){//main11();//main12();//main13();// 一元谓词//main14();// 二元谓词//main15();main16();cout << "hello..."<< endl;system("pause");}


原创粉丝点击