stl中 bind1st和 bind2nd 以及not1 等适配器的使用
在我们使用stl的 一些算法的时候,比如find_if等,需要使用仿函数,如果仿函数有2个参数,但是算法需要一个一元的仿函数的时候,我们可以使用适配器,比如:bind1st和bind2nd来将仿函数适配成一元的操作符。
bind1st表示我们绑定第一个参数,bind2st表示我们绑定第二个参数,not1表示跟想要的相反。
【详解】
可能这么解释以后大家还不是很清楚,那么就说点白话吧。
我们在做比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数,表示你程序里面的表达式要和K值去比较。
上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。
如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。
大家可能会注意到这里面没有=的比较,先别着急,后面将会说道如何实现=的比较。先举两个例子看看 bind1st和bind2nd的用法。
【实例分析】
<span style="white-space:pre"> </span>int a[] = {1, 2, 100, 200};
std::vector< int> arr(a, a + 4);
// 移除所有小于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::less< int>(), 100)), arr.end());
//这里的比较表达式相当于arr.value < 100
//如果用bind1st则表达的意思就恰恰相反
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind1st( std::less< int>(), 100)), arr.end());
//这里的表达式相当于100 < arr.value
//当然为了实现删除大于100的元素你同样可以使用bind2nd
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::greater< int>(), 100)), arr.end());
前面说道=的比较,比如说x <= k怎么实现呢,std又提供了一个好东西not1,
我们可以说 !(x > k) 和 x <= k是等价的,那么我们看看下面的表达式:
<span style="white-space:pre"> </span>// 移除所有小于等于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());
//说明:not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数。
stl 中 std::binary_function 的使用
在我们使用stl的 一些算法的时候,比如find_if等,需要使用仿函数,如果仿函数有2个参数,但是算法需要一个一元的仿函数的时候,我们可以使用适配器,比如:bind1st和bind2nd来将仿函数适配成一元的操作符。
这个时候,如果仿函数是我们自己实现的,而不是stl提供的less,greater等等内置的东东的时候,我们如果要让仿函数支持适配器,那么就必须从binary_function派生出来。
具体的例子如下:
下面这个仿函数是用来提供给find_if的,所以重载了 bool operator()操作符。
- struct TableCompareFuctorWithAdapter : public std::binary_function<STableInfor,STableInfor,bool>
- {
- public:
- TableCompareFuctorWithAdapter(){}
- ~TableCompareFuctorWithAdapter(){}
- bool operator() (const STableInfor value, const STableInfor fixedValue)const
- {
- if (value.m_sTableId == fixedValue.m_sTableId)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- };
std::binary_function<STableInfor,STableInfor,bool> 前两个表示第一,第二个参数,bool 表示 operator的返回值。
STableInfor是我自己定义的一个结构体,它我们不care,这样我们就可以在find_if中使用 bind2nd来绑定这个仿函数了。
代码如下:
- std::vector<STableInfor>::iterator iter_begin = tableInforList.begin();
- std::vector<STableInfor>::iterator iter_end = tableInforList.end();
- TableCompareFuctorWithAdapter comparefuctor;
- std::vector<STableInfor>::iterator iter_find =
- find_if(
- iter_begin,
- iter_end,
- std::bind2nd(comparefuctor, tableInfo.m_TableInfor)
- );
- if (iter_find != iter_end)
- {
- NSLog(@"find");
- }