bind1st/bingd2st用法

bind2nd和bind1nd的用法

struct printx: public binary_function<int, int, int >
{
  int operator()(int a, int b)const
  {
     cout<<a+b<<endl;
    return a+b;
  }
};
 

int main()

{

    vector<int> my;

    my.push_back(0);
    my.push_back(1);
    my.push_back(2);

    copy(my.begin(), my.end(), ostream_iterator<int>(cout, " "));

    cout<<"\n-----"<<endl;

    for_each(my.begin(),my.end(), bind2nd(printx() , 3) );

return 0;

}

以前在使用stl的过程中发现bind1st和bind2nd这两个函数,
当时不太理解什么意思,今天在网上查了一下相关资料发现竟然很简单,
下面我就具体解释一下他们的用法。

        bind1st和bind2nd函数用于将一个二元算子(binary functor,bf)
  转换成一元算子(unary functor,uf)。为了达到这个目的,
  它们需要两个参数:要转换的bf和一个值(v)。

 
         可能这么解释以后大家还不是很清楚,那么就说点白话吧。
   我们在做比较的时候所写的表达式像 x > k ,x < k,这里的
   k是一个参数表示你程序里面的表达式要和k值去比较。
   上面这两个表达式对应的应该是bind2nd ,简单的理解就是把
   k作为比较表达式的第二个参数。如果使用bind1st则对应的
   表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。
   大家可能会注意到这里面没有=的比较,先别着急,
   后面将会说道如何实现=的比较。先举两个例子看看 bind1st和bind2nd的用法。

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是等价的,那么我们看看下面的表达式:

// 移除所有小于等于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
     std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());

说明:not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数

例子需要包含头文件

#include <vector>

#include <algorithm>

#include <functional>

 

一直对取反器和绑定器的行为感到困惑,这次将VC 6.0相关的代码抽取出来,
研究了一番,终于理解了个大概,not1和bind2nd都是模板函数,
它们的功能都是返回一个函数对象,具体的工作都是由函数对象来完成的。
测试代码如下(用g++通不过编译,用VC 6.0可以):

#include <iostream>
//#include <functional>  //not1,bind2nd实现所在的头文件
#include <vector>
#include <algorithm>
 
using namespace std;
 
//binary_function,unary_function这两个结构体什么也没有 ,
//仅仅有几个typedef,这样的结构体在STL的实现中被大量用到
template<class _A1, class _A2, class _R>
struct binary_function {
    typedef _A1 first_argument_type;
    typedef _A2 second_argument_type;
    typedef _R result_type;
};
 
template<class _A, class _R>
struct unary_function {
    typedef _A argument_type;
    typedef _R result_type;
};
 
//less类重载了函数运算符号,它没有任何属性,默认的构造函数什么也不会做
//正因为它没有相应的属性,所以需要绑定器来帮助它工作
//如果给less加上一个参数,那就不需要绑定器帮忙了
template<class _Ty>
struct less : binary_function<_Ty, _Ty, bool> {
    bool operator()(const _Ty& _X, const _Ty& _Y) const
    {return (_X < _Y); }
};
 
//我们这样实现一个自己的less类,可以和上面的实现比较一番
//显然STL标准实现less类是更加妥当的,less只是取到一个判断的作用
//它不应该包含判断用的数值
template<class _Ty>
struct myless
{
public:
    myless(const _Ty& _X) : m_y(_X)
    {
    }
 
    bool operator()(const _Ty& _X) const
    {return (_X < m_y); }

private:
    _Ty m_y;
};

private:
    _Ty m_y;
};
 
//binder2nd类value属性保存了比较值,它重载的函数运算符函数将这个比较值
//和接受的参数一同送给less对象处理,然后返回其判断结果
template<class _Bfn>
class binder2nd : public unary_function<_Bfn::first_argument_type, _Bfn::result_type>
{
public:
    binder2nd(const _Bfn& _X, const _Bfn::second_argument_type& _Y) : op(_X), value(_Y) {}
 
    result_type operator()(const argument_type& _X) const
    {return (op(_X, value)); }
 
protected:
    _Bfn op;
    _Bfn::second_argument_type value;
};
 
//bind2nd是一个模板函数,它返回一个bind2nd函数对象
//可以看出来第一个实例化参数_Bfn必须从binary_function派生
//否则它不会有second_argument_type,less结构体便是从
//binary_function派生的
template<class _Bfn, class _Ty> inline
binder2nd<_Bfn> bind2nd(const _Bfn& _X, const _Ty& _Y)
{
    return (binder2nd<_Bfn>(_X, _Bfn::second_argument_type(_Y)));
}
 
//unary_negate类简单地将_Fn(_X)取反
template<class _Ufn>
class unary_negate : public unary_function<_Ufn::argument_type, bool>
{
public:
    explicit unary_negate(const _Ufn& _X) : _Fn(_X) {}
 
    bool operator()(const _Ufn::argument_type& _X) const
    {
        return (!_Fn(_X));
    }
 
protected:
    _Ufn _Fn;
};
 
//not1也是一个模板函数
//它返回一个unary_negate函数对象
template<class _Ufn> inline
unary_negate<_Ufn> not1(const _Ufn& _X)
{
    return (unary_negate<_Ufn>(_X));
}
 
int main()
{
    vector<int> vec;
 
    vec.push_back(4);
    vec.push_back(7);
    vec.push_back(5); 

    //下面两句的的作用是一样的,bind2nd可以被默认实例化

    //vector<int>::iterator iter = find_if(vec.begin(), vec.end(), bind2nd(less<int>(), 5));

    vector<int>::iterator iter = find_if(vec.begin(), vec.end(),
 bind2nd<less<int>, int>(less<int>(), 5));

    //使用我们自己实现的myless类

    myless<int> my(5);

    //这里就不需要使用绑定器了

    vector<int>::iterator iter = find_if(vec.begin(), vec.end(), my);
 
    cout << *iter << endl;  //结果为4
 
    return 0;
}

find_if(vec.begin(), vec.end(),
 bind2nd<less<int>, int>(less<int>(), 5));

 这个函数的含义是,对vec中的每一项,调用bind2nd对象的operator() 函数,相当于:

bind2nd<less<int>, int>(less<int>(), 5).operator()( *itr )

bind2nd<less<int>, int>(less<int>(), 5) 是一个binder2nd 类的对象,它

的模板参数有两个,一个是less<int>类,一个是int类型, 这个对象的构造函数有两个

参数,一个是less<int>类的临时对象,一个是int 5。

构造函数中初始化 less<int> 类的成员变量op和 类成员变量 value,op初始化为

临时对象less<int>(), value初始化为5;

bind2nd<less<int>, int>(less<int>(), 5).operator()( *itr )

相当于调用:

op( *itr,  vallue );  也就是  less<int> (  *itr, 5  );

要求第一个参数类型 为继承自binary_function的类,也就是这里的less<int>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值