bind1st、bind2nd源码分析

概述

bind1st 和 bind2nd 函数把一个二元函数对象绑定成为一个一元函数对象。但是由于原来的二元函数对象接受两个参数,在绑定成为一元函数对象时需要将原来两个参数中的一个绑定下来,也就是通过绑定二元函数对象的一个参数使之成为一元函数对象的参数。bind1st是绑定第一个参数,bind2nd则是绑定第二个参数。

这也就是说,bind1st 和 bind2nd 函数把less<int>这样的二元函数对象绑定成一个一元函数对象,现在只接受一个参数。

下面先看一下bind2nd的源代码

//这个是实际的配接器对象形式
template <class Operation>
class binder2nd
	: public unary_function<typename Operation::first_argument_type,
	typename Operation::result_type> {
protected:
	Operation op;
	typename Operation::second_argument_type value;
public:
	binder2nd(const Operation& x,
		const typename Operation::second_argument_type& y)
		: op(x), value(y) {}
	typename Operation::result_type
		operator()(const typename Operation::first_argument_type& x) const {
		return op(x, value);
	}
};
//这个是对外接口
template <class Operation, class T>
inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
	typedef typename Operation::second_argument_type arg2_type;
	return binder2nd<Operation>(op, arg2_type(x));
}

class Operation代表的是一个二元函数对象。对外接口配接器bind2nd接受两个参数,一个是二元函数对象,另一个是一个普通值,这个值作为二元函数对象的第二个参数绑定到了一元函数对象,使其成为一元函数对象的参数。类binder2nd继承了unary_function变成了一元函数对象。

binder2nd(const Operation& x,
            const typename Operation::second_argument_type& y) 
      : op(x), value(y) {}

上面这个是函数对象的构造函数的参数类型。所以,对外接口bind2nd中给binder2nd传的参数是(op,arg2_type(x)),代表了二元函数对象的第二个参数。这个概念必须分清,否则就理解不了bind2nd的过程。
 

bind1st的源代码

template <class Operation> 
class binder1st
  : public unary_function<typename Operation::second_argument_type,
                          typename Operation::result_type> {
protected:
  Operation op;
  typename Operation::first_argument_type value;
public:
  binder1st(const Operation& x,
            const typename Operation::first_argument_type& y)
      : op(x), value(y) {}
  typename Operation::result_type
  operator()(const typename Operation::second_argument_type& x) const {
    return op(value, x); 
  }
};

template <class Operation, class T>
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
  typedef typename Operation::first_argument_type arg1_type;
  return binder1st<Operation>(op, arg1_type(x));
}

原理与bind2nd一样,只不过是binder1st绑定的是二元函数对象的第一个参数而已。

举例

int main()
{
	vector<int> v{ 1,8,6,9,3 ,10,11};
	//绑定的是第二个参数,所以结果就是<7,即找比7小的元素个数
	auto n = count_if(v.begin(), v.end(), bind2nd(less<int>(), 7));
	//绑定的是第一个参数,所以结果就是7<,即找比7大的元素个数
	auto m = count_if(v.begin(), v.end(), bind1st(less<int>(), 7));
	cout << n << endl;
	cout << m << endl;
	system("pause");
	return 0;
}

说明:

bind2nd(less<int>(),7),less<int>()和7是bind2nd的构造函数所需要的两个参数,然后执行Pred(*_First),这时候就引起了运算符()的重载,此时这个*_First就是[first,last)。

 

count_if的源代码

指定操作(一个仿函数)pred实施于[first,last)区间内的每一个元素身上,并将“造成pred之计算结果为true”的所有元素的个数返回。

template<class _InIt,
	class _Pr> inline
	typename iterator_traits<_InIt>::difference_type
		count_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// count elements satisfying _Pred
	_DEBUG_RANGE_PTR(_First, _Last, _Pred);
	return (_Count_if(_Unchecked(_First), _Unchecked(_Last), _Pred));
	}
template<class _InIt,
	class _Pr> inline
	typename iterator_traits<_InIt>::difference_type
		_Count_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// count elements satisfying _Pred
	typename iterator_traits<_InIt>::difference_type _Count = 0;

	for (; _First != _Last; ++_First)
		if (_Pred(*_First))//如果元素带入pred的运算结果为true
			++_Count;//计数器累加一
	return (_Count);
	}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值