一、必要的概念
● 判斷式是返回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就是不純的,看下面...