STL演算法之for each

2022-06-07 18:12:08 字數 3081 閱讀 6767

簡單來將,仿函式(functor)就是乙個過載了"()"運算子的struct或class,利用物件支援operator()的特性,來達到模擬函式呼叫效果的技術。

我們平時對乙個集合類遍歷的時候,例如vector,是這樣做的:

1 for(vector::const_iterator iter = ivec.begin(); iter != ivec.end(); ++iter)

2

例如下面的**:

1 #include 2 #include 3 

4 struct state

5 7 ~state()

8 9 void setstate( int state )

10 int getstate() const

11 12 void print() const

13 14 private:

15 int m_state;

16 };

17 18 int main()

19 33

34

35 system( "pause" );

36 return 0;

37 }

這裡的for迴圈語句有點冗餘,想到了std::for_each ,為了使用for_each,我們需要定義乙個函式,如下:

void print( state* pstate )

於是就可以簡化為下面**:

std::for_each( vect.begin(), vect.end(),&print );

上面這段**有點醜陋,看起來不太爽,主要是函式指標的原因。

在這種應用環境下,c++有仿函式來替代,我們定義乙個仿函式,如下:

struct printer

};於是就可以簡化為下面**:

std::for_each( vect.begin(), vect.end(), printer() );

下面,我們初步看下 for_each 的stl原始碼實現:

1 template2   function for_each(inputiterator first, inputiterator last, function f)

3

它返回f已在演算法內部變動過的乙個副本。

f可以是普通函式,也可是仿函式。它的任何返回值都將被忽略。

其實for_each就是乙個模板函式,將for迴圈語句封裝起來,前面兩個引數都是迭代器,第三個引數是使用乙個函式指標(或仿函式),其功能是對每乙個迭代器所指向的值呼叫仿函式。

上面**還是有點冗餘,因為為了使用for_each還要單獨定義乙個函式(或仿函式),不太清爽,

呵呵,stl早為我們準備好了 mem_fun 模板函式來解決這個乙個問題,於是**再次簡化為:

std::for_each( vect.begin(), vect.end(), std::mem_fun( &state::print ) );

我們一起看看 mem_fun 的stl原始碼實現: 

1 // template function mem_fun

2 templateinline

4 mem_fun_t<_result, _ty> mem_fun(_result (_ty::*_pm)())

5

8 9 mem_fun 函式實際上是呼叫 mem_fun_t 函式,我們接著深入看看 mem_fun_t,

10 11

12 // template class mem_fun_t

13 template15 class mem_fun_t

16 : public unary_function<_ty *, _result>

17

23 24 _result operator()(_ty *_pleft) const

25

28 private:

29 _result (_ty::*_pmemfun)(); // the member function pointer

30 };

31 32 將上面這段**定義的寫的我們好看懂一點,如下:

33 34 // template class mem_fun_t

35 template< typename _result, typename _ty >

36 class mem_fun_t : public unary_function<_ty *, _result>

37 44

45 _result operator()(_ty *_pleft) const

46

49 50 private:

51 _pmemfun m_pfun; // the member function pointer

52 53 };

這樣就比較清晰了,定義了仿函式mem_fun_t內部定義了乙個類成員函式指標,仿函式構造的時候將函式指標儲存起來,當仿函式operator()被呼叫的時候,就通過與乙個類的例項關聯起來從而實現了類成員函式的呼叫。

其呼叫流程是這樣的,for_each把vector中的元素傳送給mem_fun,mem_fun自己產生乙個仿函式mem_fun_t,然後仿函式呼叫其過載的()。

上述原始碼還有最後乙個沒有說明,就是unary_function,直接上原始碼:

1 // template struct unary_function

2 template4 struct unary_function

5 ;

就乙個模板結構體。沒有資料成員,非常簡單。

最後,定義乙個刪除指標的仿函式:

struct deletepointer

};然後呼叫,就乙個逐一刪除vector裡面的所有元素了。

std::for_each( vect.begin(), vect.end(), deletepointer() );

STL演算法之for each

轉接自stl演算法 for each 對區間裡每個元素執行相應操作 注 for each 接受乙個操作,操作可改動所接受實參 所以該實參必須以by reference方式傳遞 include include include using namespace std for each 對區間裡每個元素執...

STL之演算法

演算法是指解決問題的方 而完整的描述,對於規範的輸入,在有限時間內要獲得所需要的輸出。不同的演算法可能使用不同的時間 空間或效率完成同樣的任務。想要評估乙個演算法的好壞,目前可以通過時間複雜度和空間複雜度來進行衡量。時間複雜度,是指演算法執行指令所需的計算量。演算法的執行時間和其所要處理的資料之間存...

STL之排序演算法

1.merge 以下是排序和通用演算法 提供元素排序策略 merge 合併兩個有序序列,存放到另乙個序列。例如 vecinta,vecintb,vecintc是用vector宣告的容器,vecinta已包含1,3,5,7,9元素,vecintb已包含2,4,6,8元素 vecintc.resize ...