STL學習之十二:函式物件和謂詞
阿新 • • 發佈:2019-02-18
本文主要介紹函式物件和謂詞的示例程式碼。函式物件是屬於類物件,能突破函式的概念 ,用以保持條用狀態資訊。具體的使用資訊科參見程式碼中的註釋部分。
示例程式碼主要包含:
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 = v3 void 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"); }