STL 用純函式做判斷式

2021-07-25 12:55:12 字數 1661 閱讀 9733

一、必要的概念

●     判斷式是返回bool(或者其他可以隱式轉化為bool的東西)。判斷式在stl中廣泛使用。標準關聯容器的比較函式是判斷式,判斷式函式常常作為引數傳遞給演算法,比如find_if和多種排序演算法。

●     純函式是返回值只依賴於引數的函式。如果f是乙個純函式,x和y是物件,f(x, y)的返回值僅當x或y的值改變的時候才會改變。 

●     乙個判斷式類是乙個仿函式類,它的operator()函式是乙個判斷式,也就是,它的operator()返回true或false(或其他可以隱式轉換到true或false的東西)。正如你可以預料到的,任何stl想要乙個判斷式的地方,它都會接受乙個真的判斷式或乙個判斷式類物件。

二、舉例:不用純函式判斷式

考慮下面(壞的實現)的判斷式類。不管傳遞的是什麼實參,它嚴格地只返回一次true:第三次被呼叫的時候。其他時候它返回假。

class badpredicate:  public unary_function               

bool operator()(const widget&)

private:

size_t timescalled;};

假設我們用這個類來從乙個vector中除去第三個widget:

// 建立vector,然後

vectorvw;                              

// 放一些widgets進去

...// 去掉第三個widget;

vw.erase(remove_if(vw.begin(), vw.end(), badpredicate()),  vw.end());

這段**看起來很合理,但對於很多stl實現,它不僅會從vw中除去第三個元素,它也會除去第六個!

要知道這是怎麼發生的,就該看看remove_if一般是怎麼實現的。記住remove_if不是一定要這麼實現:

template

fwditerator remove_if(fwditerator begin, fwditerator end, predicate p)}

這段**的細節不重要,但注意判斷式p先傳給find_if,後傳給remove_copy_if。當然,在兩種情況中,p是傳值——是拷貝——到那些演算法中的。

最初呼叫remove_if(使用者**中要從vw中除去第三個元素的那次呼叫)建立乙個匿名badpredicate物件,它把內部的timescalled成員清零。這個物件(在remove_if內部叫做p)然後被拷貝到find_if,所以find_if也接收了乙個timescalled等於0的badpredicate物件。find_if「呼叫」那個物件直到它返回true,所以呼叫了三次,find_if然後返回控制權到remove_if。remove_if繼續執行後面的呼叫remove_copy_if,傳p的另乙個拷貝作為乙個判斷式。但p的timescalled成員仍然是0!find_if沒有呼叫p,它呼叫的只是p的拷貝。結果,第三次remove_copy_if呼叫它的判斷式,它也將會返回true。這就是為什麼remove_if最終會從vw中刪除兩個widgets而不是乙個。

STL演算法之判斷式

轉接自stl演算法 1.equal v1.beg,v1.end,v2.beg,perd 判斷v1區間是否所有元素與v2子區間對應滿足謂詞perd 2.is permutation v1.beg,v1.end,v2.beg,perd 判斷v1區間是否任何元素都能在v2子區間找到滿足謂詞perd 3.m...

用斷言做邏輯判斷

說明測試環境 測試介面專案 用jmeter做壓測壓測 結論 暫無 說明上個月跳槽到了現在的公司,這裡的架構師推薦的乙個做法讓我新奇又懷疑 用斷言來做業務邏輯的判斷。這位架構師的說法是這樣的 我們的系統有2種異常,系統異常和業務異常。比如登入操作,如果密碼不對,那就是密碼不對異常!斷言拋異常我們一般都...

函式式程式設計之純函式

純函式 我們應該還記得初中的一些數學知識,函式f的概念就是,對於輸入x產生乙個輸出y f x 這就是普通的純函式。它的定義是 相同的輸入,結果總會得到相同的輸出,而且沒有任何可觀察的 也不依賴外部環境的狀態。最常見的乙個例子就是在我們運算元組的時候slice就是純函式,splice就是不純的,看下面...