今天看到<<C++ Primer>>一書課後習題14.42,問題如下:
使用標準庫函數對象及適配器定義一條表達式,令其:統計大於1024的值有多少個。
解題利用標準庫函數對象類greater<int> 答案爲:
count_if(vec.begin(),vec.end(),bind2nd(greater<int>(),1024));
這樣就牽扯出了bind1st 和 bind2nd 這兩個捆綁函數。
這兩個適配器函數和標準庫函數對象類都是定義在functional頭文件中的,其中,bind是捆綁的意思,1st和2nd分別是first和second的意思。
兩者函數聲明如下:
bind1st(const Operation& op, const T& x)
bind2nd(const Operation& op, const T& x)
bind1st函數代表這麼一個操作: x op value; bind2nd函數代表:value op x。
其中,value 是被應用bind函數的對象。這兩個適配器函數都用於將一個二元算子轉換成一個一元算子。
例子1:我們想知道一個vector中元素值大於100的元素個數,利用bind1st函數和less<int>標準庫對象類,就是使得
100<element,代碼如下:
#include "stdafx.h"
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vec;
int a;
while (cin >> a)
vec.push_back(a);
cout << count_if(vec.begin(), vec.end(), bind1st(less<int>(), 100));//100 < element?
cout << endl;
return 0;
}
結果:
輸入:1000 243 2 4 6
輸出:2(大於100的元素個數爲2)
如果我們要知道容器中小於100的元素的個數,我們可以改爲:
bind2nd(less<int>(),100) //element<100?
當然,這個也等價於:
bind1st(greater<int>(),100) //100>element?
例子2:刪除一個vector中值大於100的元素
用bind1st函數:
//100<element
vec.erase(remove_if(vec.begin(),vec.end(),bind1st(less<int>(),100)),vec.end());
用bind2nd函數:
//element>100
vec.erase(remove_if(vec.begin(),vec.end(),bind2nd(greater<int>(),100)),vec.end());
#include "stdafx.h"
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vec;
int a;
while (cin >> a)
vec.push_back(a);
//remove_if()並不會改變容器中的元素的個數,而是將所有應該刪除的元素移到容器的尾部,返回一個分界的迭代器
//然後調用erase將從分界的迭代器到尾後迭代器的所有元素刪除
vec.erase(remove_if(vec.begin(),vec.end(),bind1st(less<int>(),100)),vec.end());
for (auto c : vec)
cout << c << endl;
return 0;
}
說了這麼多,bind1st和bind2nd 的最重要區別就是 操作對象的順序相反!