STL中bind1st和bind2nd之解析

今天看到<<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 的最重要區別就是 操作對象的順序相反!






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