c++函數適配器(1)——binder1st和binder2nd

這兩天在看c++ STL模板庫,被函數適配器折磨得死去活來的,查閱了很多資料,終於有點小小的見解。

我們現在想做的事情是找出vector中大於5的數的個數,我們當然會立刻想到用for循環來寫,比如下面的方式

for(std::vector<int>::iterator ite = vec.begin(), ite != vec.end(), ++ ite)

{

   if(5< *ite)

   ++count;

}

這樣做是正確的,但是當我們學了泛型算法,我們就會找到更爲合適的方法來達到這個目的,並且能保證正確性和簡潔性,比如

count_if,count_if需要傳入一個函數對象,但問題在於我們還要傳入一參數5,讓容器的所有數都和5做比較,這個時候函數對象適

配器就隆重登場了,讓我們來看看,它是怎麼工作得。

首先我將STL中的binder1st的源碼中最重要的部分擺出來,稍微做一些修改,注意完全是爲了我們好理解。

binder1st:

template<class T>
class binder1st:public unary_function<typename T::second_argument_type,typename T::result_type>
{
//最核心代碼,我們需要理解的部分

binder1st(const T& X, const typename T::first_argument_type& Y):

        op(X),value(Y){} //構造函數將X作爲運算符,然後傳入一個綁定爲常量的值

result_type operator() ( const  argument_type& X) const
{
return (op(value,X));
private:
T op; //運算符
typename T::first_argument_type value; //常量值
}
}

binder1st一般不怎麼使用,在程序中一般使用bind1st,bind1st調用了binder1st類。我們來做一下測試。

int main()

{

    //聲明一個數組

      int a[] = {1,2,3,4,5,6,7,8};

       const int N = sizeof(a)/sizeof(int);

std::vector<int> vec(a,a+N);

int vcount = std::count_if(vec.begin(),vec.end(),std::bind1st(std::less<int>(),5));

       std::cout<<vcount<<std::endl;

       return 0;

}
我們對上面的程序調用做一下說明,調用bind1st(std::less<int>(),5),將less<int>()這個操作符傳入到binder1st的構造函數中去,相當

於OP現在代表的是less<int>(),而binder1st::value = 5,在後面的算法中就會調用op(value,X)less(5,*iter),就相當於是每一次比較是否有

5<*iter,如果結果爲真,則返回true,否則返回false。同理binder2nd的實現原理和binder1st類似,不過不同在於在後面執行op操作

的時候是採用op(X,value),那上面的程序用binder2nd可以修改如下:

int main()

{

    //聲明一個數組

      int a[] = {1,2,3,4,5,6,7,8};

       const int N = sizeof(a)/sizeof(int);

std::vector<int> vec(a,a+N);

int vcount = std::count_if(vec.begin(),vec.end(),std::bind2nd(std::greater<int>(),5));

       std::cout<<vcount<<std::endl;

       return 0;

}

輸出的結果都是3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章