仿函數(shù)紫新、仿函數(shù)類馍刮、函數(shù)等
條款38:把仿函數(shù)類設(shè)計為用于值傳遞
STL中的習慣是當傳給函數(shù)和從函數(shù)返回時函數(shù)對象也是值傳遞的(也就是拷貝)。最好的證據(jù)是標準的for_each聲明勉吻,這個算法通過值傳遞獲取和返回函數(shù)對象:
template Function // 注意值返回
for_each(InputIterator first, InputIterator last, Function f); // 注意值傳遞
條款39:用純函數(shù)做判斷式
先介紹兩個概念–“純函數(shù)”與“判別式”:
純函數(shù)是返回值只依賴于參數(shù)的函數(shù)糟需。如果f是一個純函數(shù),x和y是對象览芳,f(x, y)的返回值僅當x或y的值改變的時候才會改變斜姥。
判斷式是返回bool(或者其他可以隱式轉(zhuǎn)化為bool的東西)。判斷式在STL中廣泛使用路操。標準關(guān)聯(lián)容器的比較函數(shù)是判斷式疾渴,判斷式函數(shù)常常作為參數(shù)傳遞給算法,比如find_if和多種排序算法屯仗。
判斷式類是仿函數(shù)類搞坝,它的operator()函數(shù)是一個判斷式,也就是魁袜,它的operator()返回true或false(或其他可以隱式轉(zhuǎn)換到true或false的東西)桩撮。
重要結(jié)論:判斷式函數(shù)必須是純函數(shù)
條款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因
假設(shè)有一個可以測試Widget的函數(shù)峰弹,
void test(Widget& w); // 測試w店量,如果沒通就標記為“failed”
此外,有一個Widget的容器:
vector vw; // vw容納Widget
要測試vw中的每個Widget鞠呈,顯然可以這么使用for_each:
for_each(vw.begin(), vw.end(), test); // 調(diào)用#1(可以編譯)
但如果test是Widget的成員函數(shù)而不是非成員函數(shù)融师,也就是說,Widget支持自我測試:
class Widget {
public:
void test(); // 進行自我測試蚁吝;如果沒通過就把*this標記為“failed”
};
如果使用for_each對vw中的每個對象調(diào)用Widget::test:
for_each(vw.begin(), vw.end(),&Widget::test); // 調(diào)用#2(不能編譯)
解釋:STL里的一個普遍習慣:函數(shù)和函數(shù)對象總使用非成員函數(shù)的語法形式調(diào)用旱爆,而不直接支持成員函數(shù)的調(diào)用
為了解決這個問題,mem_fun和mem_fun_ref便提出來了:
list lpw; // 同上
...
for_each(lpw.begin(), lpw.end(),mem_fun(&Widget::test)); // 這個現(xiàn)在可以編譯了