在讨论仿函数之前,我们先来看看sort排序的第二种用法:
bool compare(int x,int y){
return x < y;
}
int main(){
vector<int>vec;
for (int i = 0; i < 10; i++){
vec.push_back(rand()%50);
cout << vec[i]<<" ";
}
cout << endl << endl;
sort(vec.begin(),vec.end(),compare);
for (int i = 0; i < 10; i++)cout << vec[i]<<" ";
cout << endl << endl;
return 0;
}
它告诉sort务必排序后的两两相邻的元素都能令该操作为true,在compare函数中,我们希望x<y这个操作在容器vec里的任意相邻元素都为真;虽然函数指针可以达到“将整组操
作当作算法的操作”,但是它不够灵活,无法满足对抽象性的要求,于是就产生了仿函数,它其实就是一个“行为类似函数”的类对象,在这个类对象内将上述的compare函数进行
封装,下面来看看less和plus两个类的实现源码:
1. less
template<class T>
struct less :public binary_function<T,T,bool>{
bool operator()(const int& x, const int& y) const {
return x < y;
}
};
2. plus
template<class T>
struct plus :public binary_function<T,T,T>{
T operator()(const int& x, const int& y) const {
return x + y;
}
};
3.unary_function和binary_function
template <class _Arg, class _Result>
struct unary_function {
typedef _Arg argument_type;
typedef _Result result_type;
};
// 二元函数,模板参数:参数1的类型,参数2的类型,返回值类型。
// 注意参数的位置,如果它被继承,主要是提供了3个typedef。
template <class _Arg1, class _Arg2, class _Result>
struct binary_function {
typedef _Arg1 first_argument_type;
typedef _Arg2 second_argument_type;
typedef _Result result_type;
};
int main(){
vector<int>vec;
for (int i = 0; i < 10; i++){
vec.push_back(rand()%50);
cout << vec[i]<<" ";
}
cout << endl << endl;
less<int>le;
sort(vec.begin(),vec.end(),le);
for (int i = 0; i < 10; i++)cout << vec[i]<<" ";
cout << endl << endl;
return 0;
}
下面以bind2nd来说明:
int main(){
vector<int>vec;
for (int i = 0; i < 10; i++){
vec.push_back(rand()%100);
cout << vec[i]<<" ";
}
cout << endl << endl;
less<int>le;
cout << count_if(vec.begin(),vec.end(),not1(bind2nd(le,50))) << endl;
return 0;
}
下面是bind2nd的源码:
template<class _fn2,class _ty>
inline binder2nd<_fn2> bind2nd(const _fn2& _func, const _ty& _right){ // return a binder2nd functor adapter
typename _fn2::second_argument_type _val(_right);//此处将仿函数multiplies<int>临时对象的第二个参数设置为10
return (_std binder2nd<_fn2>(_func, _val)); //返回模板类binder2nd临时对象
}
template<class _fn2>
class binder2nd: public unary_function<typename _fn2::first_argument_type,typename _fn2::result_type> { //
public:
typedef unary_function<typename _fn2::first_argument_type,typename _fn2::result_type> _base;
typedef typename _base::argument_type argument_type;
typedef typename _base::result_type result_type;
binder2nd(const _fn2& _func,
const typename _fn2::second_argument_type& _right) //构造函数,仿函数第二个参数被赋值
: op(_func), value(_right)
{ // construct from functor and right operand
}
result_type operator()(const argument_type& _left) const //调用仿函数
{ // apply functor to operands
return (op(_left, value));
}
result_type operator()(argument_type& _left) const
{ // apply functor to operands
return (op(_left, value));
}
protected:
_fn2 op; // the functor to apply
typename _fn2::second_argument_type value; // the right operand
};
下面是个人试验:
template<class T>
void func(T x,int y){ //获得x(less<int>)的型别
typedef typename T::second_argument_type type;
type cc=y;
cout << x(1,2) << endl;
cout << sizeof(cc) << endl;
cout << cc << endl;
}
int main(){
vector<int>vec;
for (int i = 0; i < 10; i++){
vec.push_back(rand()%100);
cout << vec[i]<<" ";
}
cout << endl << endl;
less<int>le;
int b = 9;
func(le, 9);
sort(vec.begin(),vec.end(),le);
for (int i = 0; i < 10; i++){
cout << vec[i] << " ";
}
return 0;
}