先弄清幾個概念,什么叫一元函數,二元函數
1. 一元函數一個參數
2. 二元函數 兩個參數
3. 一元謂詞 一個參數,返回類型為bool型
4. 二元謂詞 兩個參數,返回類型為bool型
函數適配器是用來讓一個函數對象表現出另外一種類型的函數對象的特征。因為,許多情況下,我們所持有的函數對象或普通函數的參數個數或是返回值類型並不是我們想要的,這時候就需要函數適配器來為我們的函數進行適配
C++中有三類適配器,分別是容器適配器,迭代器適配器和函數適配器,這里主要介紹函數適配器。
函數適配器用於特化和擴展一元二元函數對象,函數適配器主要有以下兩類:
1 綁定器
該類適配器用於將二元函數適配成一元函數
將二元函數的一個參數綁定到一個特定的值上,將二元函數對象轉換成一元函數對象。
綁定器適配器有兩種:bind1st bind2nd。每個綁定器接受一個函數對象和一個值
bind1st將給定值綁定到二元函數對象的第一個實參
bind2nd將給定值綁定到二元函數對象的第二個實參
例子:
先看下count_if的普通用法
count_if: 利用輸入的函數,對標志范圍內的元素進行比較操作,返回結果為true的個數。例如:vecInt是用vector<int>聲明的容器,已包含1,3,5,7,9元素,現要求求出大於等於3的元素個數
bool GreaterThree(int iNum) { if(iNum>=3) { return true; } else { return false; } } int iCount = count_if(vecIntA.begin(),vecIntA.end(), GreaterThree); //這里要求GreaterThree的函數參數必須是一個 //此時iCount == 4 count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(), 10)); // less_equal<int>()函數是兩個參數,怎樣讓他變成一個參數呢? less_equal是STL為我們提供的一個函數對象,它有兩個參數,其作用是比較第一個參數值是否<=第二個參數值。但是count_if要求我們第三個參數必須是一個一元謂詞(就是只有一個參數),所以我們用bind2nd對該函數對象進行適配,將10綁定到該函數對象的第二個參數上。 (意思就是說less_equal<int>( _Left, _Right)這個函數只要他的第二個參數,第一個參數忽略) 現在cont_if執行的功能實際上就變成了查找給定序列中值<=10的元素的個數
2 取反器 將函數對象的結果真值求反
取反器有兩種:not1和not2
not1是對一元函數對象求反的取反器,傳遞給函數對象的只有一個參數,則要使用這個not1
not2是對二元函數對象求反的取反器
例子
int* where=find_if(&array[0],&array[100],not1(bind2nd(breater<int>(),200)))
推薦一個很好的判斷傳參的方法:先寫一個類,重載()算符,並接受傳遞進來的參數,判斷后再返回真假
例子:
#include <functional> #include <iostream> #include <ctime> #include <cstdlib> #include <cassert> #define ASSERT assert using namespace std; class Rand:public binary_function<int, int, int> { public: Rand() { srand((unsigned int)time(NULL)); } int operator()(int minval, int maxval) const { ASSERT(maxval>minval); ASSERT(minval>=0); ASSERT(maxval<=RAND_MAX); return (rand()%(maxval-minval)) + minval; } }; int main() { cout<<Rand()(1,5)<<endl; //[1,5) cout<<bind1st(Rand(),20)(30)<<endl; return 0; }