關於在STL容器list中使用find if 函式

2021-04-21 07:28:52 字數 4054 閱讀 6003

classdisplay

現基於list

容器已經建立起具有若干節點(

1~30

)的list

,並根據實際需要增添新的節點,要求新增的節點的

name

要和list

中所有節點的

name

不同,我想到的方案是:在呼叫

push_back

之前,先對

list

進行搜尋,檢查是否已經存在和新增的節點的

name

相同的節點。若不存在,則可以呼叫

push_back

新增新節點,否則提示已經存在

name

相同的節點。其中

name

的值是在執行期由使用者通過文字輸入框(

edit

)輸入的字串來確定的。實現過程,可以使用兩種方式樣式來配合演算法

find_if

:使用輔助函式

unary predicates

和使用訪函式(或稱函式物件)(

functors

or function objects)。

★使用輔助函式

unary predicates :

演算法有一種特殊的輔助函式叫做

predicates

(判別式或謂詞)。所謂

predicates

,就是返回布林值的函式。它們通常被用來指定搜尋準則和排序準則,

predicates

可能有乙個或兩個運算元,視情況而定。注意:並非任何返回布林值的一元函式或二元函式都是合法的

predicates

。stl

要求,面對相同的值,

predicates

必須得出相同的結果,這條戒律將那些

「被呼叫時,會改變自己內部狀態

」的函式清除出場。

如果兩次用到這樣的函式,每次使用者輸入的字串不同,而且都是在執行時期才處理,則必須在函式被呼叫之前先將使用者輸入的字串傳給該函式,通常會導致使用一些全域性變數,

「演算法的呼叫者」和

「演算法所呼叫的函式

」都會用到它們。

listdisplays_list

;        //

全域性變數

string newname

;                          //

全域性變數

boolcheckbesamename (display& x)

else}

void__fastcalltform::button_addclick (tobject *sender)

} 例子中

find_if

演算法在給定區間(

ranges

)內搜尋使

「被傳入的一元判別式

」返回結果為

true

的第乙個元素的迭代器,即返回給定區間內

name

成員的字串資料值等於使用者輸入的字串(

newname

)的第乙個

display

節點。如果沒有任何節點匹配這個(

name

成員的字串值等於使用者輸入的字串

newname

)條件。

find_if

演算法就返回區間的終點(也就是演算法

find_if

的第二個引數)。

★使用訪函式(或稱函式物件)(

functors

or function objects

傳遞給演算法的

「函式型引數」(

functional arguments

),並不一定得是函式,也可以是行為類似函式的物件。這種物件稱為

function object

(函式物件)或稱

functor

(訪函式)。仿函式是泛型程式設計強大威力和純粹抽象概念的又乙個例證,可以說,任何東西,只要其行為像函式,它就可以被當作函式來用。什麼才是具備函式行為(也就是行為像個函式)呢?所謂函式行為,是指可以

「使用小括號傳遞引數,藉以呼叫某個東西

」。如果你指望物件也可以具備函式行為,就必須讓它們也可以被「呼叫」——通過小括號的運用和引數的傳遞。只需要定義

operator

(),並給予合適的引數類別:

classx ;

...... }

為了獲得

c++標準程式庫的保證行為,不應該傳遞乙個

「行為取決於被拷貝次數或被呼叫次數

」的仿函式,也就是說,如果以兩個相同的引數來呼叫乙個單引數判別式(

unary predicate

),該判別式應該總是返回相同的結果。換句話說,判別式不應該因為被呼叫而改變自身狀態。判別式的副本和其正本有著相同狀態,要做到這一點,一定得保證不應該因為函式呼叫而改變判別式狀態,應該將

operator

()宣告為

const

成員函式。

相對於一般函式,訪函式有它的優點: 1

、仿函式是

smart functions

(智慧型函式):

「行為類似指標

」的物件,我們稱為

「smart pointers」。

「行為類似函式

」的物件,同樣道理,我們可以稱之為

「smart functions

」,因為它們的能力可以超越

operator

()。仿函式可以擁有成員函式和成員變數,這意味著仿函式擁有狀態(

state

)。事實上,在同一時間裡,由某個仿函式所代表的單一函式,可能有不同的狀態,這在一般函式中是不可能的。另乙個好處是:可以在執行期(

runtime

)初始化它們——當然必須在它們被使用(被呼叫)之前。

2

、每個仿函式都有自己的型別:一般函式,唯有在它們的標記式(

signatures

)不同時,才算型別不同。而仿函式即使標記式相同,也可以有不同的型別。事實上,有仿函式定義的每乙個函式行為都有自己的型別。這對於「利用

template

實現泛型程式設計

」是乙個卓越貢獻,由此,我們可以將函式行為當作

template

引數來運用。這使得不同型別的容器可以使用型別的仿函式作為排序準則。這可以確保不會在排序準則不同的群集(

collections

)之間賦值、合併或比較。甚至可以設計仿函式繼承體系(

functions hierarchies

),以此完成某些特別事情,例如在乙個總體原則下確立某些特殊情況。 3

、仿函式通常比一般函式速度快:就

template

而言,由於更多細節在編譯期就已確定,所以通常可能進行更好的最佳化,所以,傳入乙個仿函式(而非一般函式),可以獲得更好的效能。

listdisplays_list

;        //

全域性變數(避免了使用全域性變數

string newname

的形式)

classcheckbesamename  

// 建構函式(初始化行初始化)

// 無引數時可省略(使用預設的)

booloperator() (display &x)const

else}

};void__fastcalltform::button_addclick (tobject *sender)

}

教你使用STL容器之list

相較於vector的連續線性空間,list就稍微有點複雜,它的好處是每次插入或刪除乙個元素,就配置或釋放乙個元素空間。list對於空間的運用有絕對的精準,一點也不浪費,而且對於任何位置元素的插入和刪除,list時間複雜度為o 1 list底層是乙個帶頭結點的雙向迴圈鍊錶。list的插入和刪除操作都不...

STL順序容器 list

list是乙個線性鍊錶結構,它的資料由若干個節點構成,每乙個節點都包括乙個 息塊 即實際儲存的資料 乙個前驅指標和乙個後驅指標。它無需分配指定 記憶體大小且可以任意伸縮,這是因為它儲存在非連續的記憶體空間中,並且由指 針將有序的元素鏈結起來。由於其結構的原因,list 隨機檢索的效能非常的不好,因為...

STL通用容器之 list 容器

list容器 相對於vector的連續線性空間,list是乙個雙向鍊錶,它有乙個重要性質 插入操作和刪除操作都不會造成原有的list迭 器失效,每次插入或刪除乙個元素,就配置或釋放乙個元素空間。也就是說,對於任何位置的元素插入或刪除,list 遠是常數時間。1 建構函式 listc 建立乙個空的li...