您好,登錄后才能下訂單哦!
這篇文章主要介紹“C++中的函數對象及函數適配器的功能”,在日常操作中,相信很多人在C++中的函數對象及函數適配器的功能問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++中的函數對象及函數適配器的功能”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
1 函數對象
2 STL提供的函數對象
3 函數適配器
總結
1.函數對象是行為類似函數的對象。一個類對象,表現出一個函數的特征,即通過對象名+(參數列表)的方式使用一個類對象。
2.使用STL中提供的或自定義的迭代器和**函數對象,**配合STL的算法,組合出各種各樣的功能。
3.通過函數對象而不使用函數指針,可以增加通用性,提高效率。
4.函數對象概念:泛化的函數
①將普通函數作為函數對象:傳遞函數名
#include <iostream> #include <numeric> //包含accumulate算法 #include <functional> #include <vector> using namespace std; int mult(int a, int b) { return a * b; } int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7 }; const int N = sizeof(a) / sizeof(int); //用該式確定數組長度,定義為常量 cout << "所有數累乘為:" << accumulate(a, a + N, 1, mult) << endl; //將普通函數作為函數對象,傳遞函數名 //指針a,a + N也可以作為迭代器 return 0; }
②將重載了()運算符的類的對象作為函數對象:傳遞"類名()"
#include <numeric> #include <iostream> using namespace std; class MultClass { public: int operator () (int a, int b) const { return a * b; } }; int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7 }; const int N = sizeof(a) / sizeof(int); //確定數組a的長度 cout << "所有數乘積為:" << accumulate(a, a + N, 1, MultClass()) << endl; //傳輸方式是類名(),輸出5040 //指針a,a + N也可以作為迭代器 MultClass ss; cout << ss(100, 100); //輸出10000 return 0; }
1.系統提供函數對象幫助實現基本功能。
2.accmulate算法接受二元函數對象,transform算法接受一元函數對象。
①STL庫的multiplies
#include <iostream> #include <functional> #include <numeric> using namespace std; int main(){ int a[] = { 1, 2, 3, 4, 5, 6, 7 }; const int N = sizeof(a) / sizeof(int); cout << accumulate(a, a + N, 1, multiplies<int>()) << endl;//通過STL自帶的函數對象multiplies實現乘法,注意要寫數據類型<int> //指針a,a + N也可以作為迭代器 return 0; }
②STL庫的二元謂詞greater
#include <iostream> #include <algorithm> #include <functional> //包含greater using namespace std; int main() { int arr[] = { 24, 43, 5, 4, 62, 34, 7654, 22 }; const int N = sizeof(arr) / sizeof(int); copy(arr, arr + N, ostream_iterator<int>(cout, "\t")); cout << endl; sort(arr, arr + N, greater<int>()); //包含在<algorithm>中,默認是升序 copy(arr, arr + N, ostream_iterator<int>(cout, "\t")); return 0; }
適配器顧名思義,讓函數適配算法。
Unary Predicate:一元謂詞
binary:二元的
bind:結合,(使)聯合在一起
①找出第一個大于40的數,注意用數組和vector都可以
#include <iostream> #include <algorithm> #include <functional> #include <vector> using namespace std; int main() { int a[] = { 30, 40, 50, 90, 20, 10 }; const int N = sizeof(a) / sizeof(int); int *c = find_if(a, a + N, bind2nd(greater<int>(), 40)); cout << *c << endl; return 0; }
一般使用數組初始化向量vector,后續操作更方便
int main() { int a[] = { 30, 40, 50, 90, 20, 10 }; const int N = sizeof(a) / sizeof(int); vector<int> v (a, a + N); //用數組初始化vector vector<int>::iterator p = find_if (v.begin(), v.end(), bind2nd(greater<int>(), 40) ); if (p == v.end()) cout << "找不到" << endl; else cout << *p << endl; return 0; }
find_if算法在STL中的原型聲明為: template<class InputIterator, class UnaryPredicate> InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred); 它的功能是查找數組[first, last)區間中第一個pred(x)為真的元素。 InputIterator、UnaryPredicate是用概念來做模板參數名
②利用prt_fun、not1、not2產生組合適配器
#include <iostream> #include <functional> #include <algorithm> #include <vector> using namespace std; int g(int x, int y) { //實現類似greater的功能 return x > y; } int main() { int a[] = { 30, 90, 10, 23, 432, 656, 7, 78 }; const int N = sizeof(a) / sizeof(int); vector<int> v(a, a + N); auto p1 = find_if(v.begin(), v.end(), bind2nd(ptr_fun(g), 40)); //找第一個大于40的數 //ptr_fun將函數指針轉換為函數對象,bind2nd將40作為二元函數對象的第二個參數 if (p1 == v.end()) cout << "no element" << endl; else cout << *p1 << endl; auto p2 = find_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(g), 15))); //找第一個不大于15的數 //not1對一元函數對象取邏輯反,find_if找到第一個令bind2nd取false的值 if (p2 == v.end()) cout << "no element" << endl; else cout << *p2 << endl; auto p3 = find_if(v.begin(), v.end(), bind2nd(not2(ptr_fun(g)), 15)); // 找第一個不大于15的數 //not2對二元函數取邏輯反 if (p3 == v.end()) cout << "no element" << endl; else cout << *p3 << endl; return 0; }
③成員函數適配器,類的成員函數要通過適配器轉換為普通函數對象
#include <iostream> #include <vector> #include <functional> #include <algorithm> using namespace std; struct Car { int id; Car(int id) { this->id = id; } void display() const { cout << "car " << id << endl; } }; int main() { vector<Car*> pcars; vector<Car> cars; for (int i = 0; i < 5; i++) pcars.push_back(new Car(i)); //push_back() 在Vector最后添加一個元素(參數為要插入的值) for (int i = 5; i < 10; i++) cars.push_back(Car(i)); cout << "elements in pcars: " << endl; for_each(pcars.begin(), pcars.end(), mem_fun(&Car::display));//for_each算法對每一個迭代器范圍中的元素進行函數對象計算 //men_fun適配后函數對象的參數為"對象的指針" cout << endl; for_each(cars.begin(), cars.end(), mem_fun_ref(&Car::display)); //men_fun_ptr適配后函數對象的參數為"對象的引用" cout << endl; for (size_t i = 0; i < pcars.size(); ++i) delete pcars[i]; return 0; }
為什么不能同全局函數一樣直接傳遞函數名而成員函數必須以 &類名::函數名 的方式,因為需要考慮static成員函數的情況。
mem_fun(member適配為function):將成員函數適配為普通函數對象,適配出來的函數需要對象的指針作為參數。
men_fun_ref:將成員函數適配為普通函數對象,適配出來的函數需要對象的引用作為參數。
到此,關于“C++中的函數對象及函數適配器的功能”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。