他们在使用的时候都需要加上头文件<functional>
下面是一个关于 bind1st 的简单示例:
#include <iostream>
#include <functional>
template<typename T>
class MLess : public std::binary_function<T, T, bool>
{
public:
bool operator() (const T& a, const T& b) const{
return a < b;
}
};
int main(int argc, char** argv)
{
auto lessObj = std::bind1st(MLess<int>(), 5);
std::cout << lessObj(6) << std::endl;
system("pause");
return 0;
}
这里我们先定义了一个仿函数 MLess 用来进行两个数的比较,使用函数 bind1st 将 MLess<int>()(const T& a, const T& b) 的第一个参数绑定为5,然后传入后续的参数与5进行比较,很显然 5 < 6 的结果为 true
程序的运行结果为:
1
首先我们的自定义函数继承自类 binary_function , 关于类 binary_function 的定义很简单,源码如下:
template<class _Arg1,
class _Arg2,
class _Result>
struct binary_function
{
// base class for binary functions
typedef _Arg1 first_argument_type;
typedef _Arg2 second_argument_type;
typedef _Result result_type;
};
这是一个二元函数的模板类,定义两个输入参数,一个返回值。
关于 bind1st 的实现也非常简单,源码如下:
template<class _Fn2>
class binder1st
: public unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type>
{ // functor adapter _Func(stored, right)
public:
typedef unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type> _Base;
typedef typename _Base::argument_type argument_type;
typedef typename _Base::result_type result_type;
binder1st(const _Fn2& _Func,
const typename _Fn2::first_argument_type& _Left)
: op(_Func), value(_Left)
{ // construct from functor and left operand
}
result_type operator()(const argument_type& _Right) const
{ // apply functor to operands
return (op(value, _Right));
}
result_type operator()(argument_type& _Right) const
{ // apply functor to operands
return (op(value, _Right));
}
protected:
_Fn2 op; // the functor to apply
typename _Fn2::first_argument_type value; // the left operand
};
// TEMPLATE FUNCTION bind1st
template<class _Fn2,
class _Ty> inline
binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left)
{ // return a binder1st functor adapter
typename _Fn2::first_argument_type _Val(_Left);
return (binder1st<_Fn2>(_Func, _Val));
}
从代码中,可以轻松看出, bind1st 是一个函数模板,需要传入两个参数,_Func 和 _Left ,binder1st 是一个仿函数类,构造函数中将 _Func 赋值给了成员 op, _Left 赋值给我成员 value,重载的 () 正好调用的函数 op(value, _Right)
我们上面的例子中,
auto lessObj = std::bind1st(MLess<int>(), 5);
实际上是返回一个仿函数类 binder1st ,成员 op 为 MLess<int>() 对象, value 为 5
而调用
lessObj(6)
时,实际上是在调用函数
result_type operator()(const argument_type& _Right) const
{ // apply functor to operands
return (op(value, _Right));
}
也就是这么调用
binder1st<MLess<int>()>(6)
// 也就相当于执行下面这句
MLess<int>()(5, 6)
bind2nd 的内部实现跟 bind1st 类似,这里就不缀余了。下面是一个 bind2nd 的简单实用示例,将列表 nList 中的 >30 的数打印出来:
#include <iostream>
#include <functional>
#include <algorithm>
#include <list>
template<typename T>
class MTestClass : public std::binary_function<T, T, void>
{
public:
void operator() (const T& a, const T& b) const{
if (a > b)
std::cout << a << std::endl;
}
};
int main(int argc, char** argv)
{
std::list<int> nList;
nList.push_back(10);
nList.push_back(20);
nList.push_back(30);
nList.push_back(40);
nList.push_back(50);
nList.push_back(60);
std::for_each(nList.begin(), nList.end(), std::bind2nd(MTestClass<int>(), 30));
system("pause");
return 0;
}
程序的运行结果为:
40
50
60