概述
bind1st 和 bind2nd 函数把一个二元函数对象绑定成为一个一元函数对象。但是由于原来的二元函数对象接受两个参数,在绑定成为一元函数对象时需要将原来两个参数中的一个绑定下来,也就是通过绑定二元函数对象的一个参数使之成为一元函数对象的参数。bind1st是绑定第一个参数,bind2nd则是绑定第二个参数。
下面先看一下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变成了一元函数对象,这里不要混淆的概念是:
class binder2nd : public unary_function<typename Operation::first_argument_type, typename Operation::result_type>注意:first_argument_type表明了重载函数()的类型,而不是说函数对象的构造函数的参数类型
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; }