bind1st和bind2nd是将二元函数转换为一元函数,比如一个比较大小的函数是二元函数,当在某些情况下我们想要固定第一个参数或者第二个参数时吗,就成了一元函数,先看用法
// Created by 开机烫手 on 2018/7/24.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v;
v.push_back(2);
v.push_back(1);
v.push_back(3);
v.push_back(9);
v.push_back(7);
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
cout << endl;
cout << count_if(v.begin(), v.end(), bind2nd(less<int>(), 5) ) << endl;
return 0;
}
上面这段代码统计了vector中元素值小于5的元素个数,使用bind2nd将less仿函数的第二个参数绑定为5。接下来看看整个代码的调用过程:
template<typename _Operation, typename _Tp>
inline binder2nd<_Operation>
bind2nd(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(__fn, _Arg2_type(__x));
}
bind2nd是有两个模板参数的函数,从例子中调用的地方可以看到,第一个参数是less<int>的临时匿名函数对象,第二个是int型的数字40,less的代码为
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
_GLIBCXX14_CONSTEXPR
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function
{
/// @c first_argument_type is the type of the first argument
typedef _Arg1 first_argument_type;
/// @c second_argument_type is the type of the second argument
typedef _Arg2 second_argument_type;
/// @c result_type is the return type
typedef _Result result_type;
};
可以看到less中重载了()运算符实现比较数字大小的功能,比如使用 less<int>(2,3) 即可调用。在bind2nd中通过 _Operation 记录了less的类型,之后调用了binder2nd
template<typename _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); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
} _GLIBCXX_DEPRECATED;
这个类中定义了 _Operation 型的op对象,在构造函数中使用之前传入的临时函数对象对其进行了初始化,也重载了 () 运算符,在重载运算符函数中调用了之前的仿函数,这里对应为less(__x,40)。
应该就是这么个过程了。。。