c++仿函数浅析

在讨论仿函数之前,我们先来看看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;
}


最终可以看到所有vec容器里所有的元素都按从小到大的顺序排列,在sort函数中我们将compare函数指针作为参数传递,compare函数里面指定了用户想要执行的操作,

它告诉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;  
};  


有了仿函数之后,我们在排序的时候就只需要向sort的第三个参数传递一个函数对象即可:

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;
}








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值