日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

谓词函数、函数对象

發布時間:2024/9/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 谓词函数、函数对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
從概念上講,函數對象用作函數的對象;但是從實現上來說,函數對象時實現了 operate()的類的對象。
雖然函數和函數指針也可以歸為函數對象,但實現了operate()的類的對象才能保存狀態,才能用于STL。

我們直接看定義:
一元函數:接受一個參數的函數,如f(x)。

一元謂詞函數:如果一元函數返回一個BOOL類型的值,則該函數稱為謂詞。

二元函數:接受2個參數的函數,如f(x,y)。

二元謂詞函數:如果二元函數返回一個BOOL值,則該函數稱為二元謂詞。


之所以給返回布爾類型的函數對象專門命名,是因為謂詞是用來為算法判斷服務的。

一元函數:

下面給個很簡單的一元函數的例子:

template<typename elementType> void FuncDispalyElement(const elementType& element) {cout<<element<<endl; }

該函數也可以采用另一種表現形式,即實現在包含在類或結構的operate()中:

template<typename T> struct DispalyElememnt {void opearator()(const T& elememnt) const{cout<<element<<endl;} };

上面兩種實現都可以用于STL算法for_each,將集合中的類容顯示在屏幕上。

#include <algorithm> #include <iostream> #include <vector> #include <list>using namespace std;// struct that behaves as a unary function template <typename elementType> struct DisplayElement {void operator () (const elementType& element) const{cout << element << ' ';} };int main () {vector <int> vecIntegers;for (int nCount = 0; nCount < 10; ++ nCount)vecIntegers.push_back (nCount);list <char> listChars;for (char nChar = 'a'; nChar < 'k'; ++nChar)listChars.push_back (nChar);cout << "Displaying the vector of integers: " << endl;// Display the array of integersfor_each ( vecIntegers.begin () // Start of range, vecIntegers.end () // End of range, DisplayElement <int> () ); // Unary function object cout << endl << endl;cout << "Displaying the list of characters: " << endl;// Display the list of charactersfor_each ( listChars.begin () // Start of range, listChars.end () // End of range, DisplayElement <char> () );// Unary function objectreturn 0; }

其中for_each方法接受三個參數,前兩個分別制定范圍的起點和終點,第3個指定對范圍類的每個元素調用的函數,如對vector調用DispalyElement::operate().
雖然這里2中方法都可以,但是結構體更加強大,因為它除了擁有operate()之外,還可以擁有成員屬性,下面對之前的一元函數稍作修改:

te<typename elementType> struct DisplayElementKeepCount {int Count;// ConstructorDisplayElementKeepCount() : Count(0) {}// Display the element, hold count!void operator()(const elementType& element){++ Count;cout << element<< ' ';} };

注意:operate()不再是const成員函數,因為它對成員Count進行遞增,以記錄自己被調用用于顯示數據的次數,該計數是通過共有成員屬性Count暴露的。下面是一個例子:

#include<algorithm> #include<iostream> #include<vector> using namespace std;template<typename elementType> struct DisplayElementKeepCount {int Count;// ConstructorDisplayElementKeepCount() : Count(0) {}// Display the element, hold count!void operator()(const elementType& element){++ Count;cout << element<< ' ';} };int main() {vector<int> vecIntegers;for(int nCount = 0; nCount< 10; ++ nCount)vecIntegers.push_back(nCount);cout << "Displaying the vector of integers: "<< endl; // Display the array of integersDisplayElementKeepCount<int> Result;Result = for_each( vecIntegers.begin() // Start of range, vecIntegers.end() // End of range// ,Result); //也可以用這行代替下一行, DisplayElementKeepCount<int>() );// function object cout << endl<< endl;// Use the state stores in the return value of for_each!cout << "'"<< Result.Count<< "' elements were displayed!"<< endl;return 0; }

注意這次試用了for_each的返回值。

一元謂詞

知道了一元函數,一元謂詞也就很好理解了,下面我么給個例子,然后將一元謂詞用于std::find_if算法中:

structure as a unary predicate template <typename numberType> struct IsMultiple {numberType Divisor;IsMultiple (const numberType& divisor){Divisor = divisor;}bool operator () (const numberType& element) const{// Check if the dividend is a multiple of the divisorreturn ((element % Divisor) == 0);} };#include <algorithm> #include <vector> #include <iostream> using namespace std; int main () {vector <int> vecIntegers;cout << "The vector contains the following sample values: ";// Insert sample values: 25 - 31for (int nCount = 25; nCount < 32; ++ nCount){vecIntegers.push_back (nCount);cout << nCount << ' ';}cout << endl << "Enter divisor (> 0): ";int Divisor = 2;cin >> Divisor;// Find the first element that is a multiple of 4 in the collectionauto iElement = find_if ( vecIntegers.begin (), vecIntegers.end (), IsMultiple<int>(Divisor) ); if (iElement != vecIntegers.end ()){cout << "First element in vector divisible by " << Divisor;cout << ": " << *iElement << endl;}return 0; }

二元函數與二元謂詞

與一元函數一元謂詞一模一樣,只是參數變為2個,下面給出一個二元謂詞對字符串vector排序的例子。

#include <algorithm> #include <string> using namespace std;class CompareStringNoCase { public:bool operator () (const string& str1, const string& str2) const{string str1LowerCase;// Assign space str1LowerCase.resize (str1.size ());// Convert every character to the lower case transform (str1.begin (), str1.end (), str1LowerCase.begin (), tolower);string str2LowerCase;str2LowerCase.resize (str2.size ());transform (str2.begin (), str2.end (), str2LowerCase.begin (), tolower);return (str1LowerCase < str2LowerCase);} };#include <vector> #include <iostream>template <typename T> void DisplayContents (const T& Input) {for(auto iElement = Input.cbegin() // auto, cbegin and cend: c++11 ; iElement != Input.cend (); ++ iElement )cout << *iElement << endl; }int main () {// Define a vector of string to hold namesvector <string> vecNames;// Insert some sample names in to the vectorvecNames.push_back ("jim");vecNames.push_back ("Jack");vecNames.push_back ("Sam");vecNames.push_back ("Anna");cout << "The names in vector in order of insertion: " << endl;DisplayContents(vecNames);cout << "Names after sorting using default std::less<>: " << endl;sort(vecNames.begin(), vecNames.end());DisplayContents(vecNames);cout << "Names after sorting using predicate that ignores case:" << endl;sort(vecNames.begin(), vecNames.end(), CompareStringNoCase());DisplayContents(vecNames);return 0; }

小結:

  一元謂詞大量用于stl算法中,例如std::partition算法使用一元謂詞來劃分,stable_partition也使用一元謂詞,還有諸如find_if()等查找,remove_if()等
刪除元素的函數也使用一元謂詞。對于二元謂詞,同樣也是,如刪除響鈴重復元素unique(),排序算法sort(),以及對2個范圍進行操作的transform(),都需要二元謂詞。謂詞在stl中很有用途。

總結

以上是生活随笔為你收集整理的谓词函数、函数对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。