C++中的仿函数
2016-06-13 13:08
281 查看
端午放假回家,无意间拾起侯捷的
在algorithm算法库中有一个for_each函数用于对某个可迭代对象进行某种操作,行为类似于python中的map函数。
其核心代码如下:
我们注意到其实for_each只是对for语句的一层封装,简化书写。但是其实值得我们思考的地方在于放在for循环中的是
在stl中提供了大量有用的仿函数,比如plus,minus,multiplies,divides,modulus,equal_to,not_equal_to,greater…很多很多,根据传入的参数的个数我们可以分为只需要接受一个参数的仿函数(unary_function)和需要接收两个参数的仿函数(binary_function)。其源码实现基本类似:
比如 bit_not(按位取反)操作只需要接收一个参数:
比如最经典的我们在申明一个map时,其中map是一个需要3个泛型参数的类,其声明为
我们知道map是一个有序容器,那么到底是以如何的顺序呢?就在于第二个泛型参数
那么如果我们想把map的排列顺序改为由大到小,甚至建立自己的排序规则都只要依葫芦画瓢重写一个仿函数然后声明map时盖住默认的less行为即可。
STL大致分为六大模块:容器(container),算法(algorithm),迭代器(iterator),仿函数(functor),配接器(adapter),配置器(allocator)。其中仿函数是体积最小,观念最简单,但是在stl算法的搭配中起到了非常重要的作用,这是与简单的lambda或者指针函数所不同的。
<<STL源码剖析>>,之前一直看的不太懂,没想到今天翻到仿函数(factors)一章,竟有所收获,而且刚好与上一章讲述的函数指针很有关联,遂赶紧记录下来。
在algorithm算法库中有一个for_each函数用于对某个可迭代对象进行某种操作,行为类似于python中的map函数。
其核心代码如下:
template<class _InIt, class _Fn1> inline void _For_each(_InIt _First, _InIt _Last, _Fn1& _Func) { // perform function for each element for (; _First != _Last; ++_First) _Func(*_First); }
我们注意到其实for_each只是对for语句的一层封装,简化书写。但是其实值得我们思考的地方在于放在for循环中的是
_Func(*_First);那么从程序的角度来说,它只关心_Func能够做()操作就可以了。所以我们习惯性的会传入一个函数指针,简单的一点就是C++11标准中的lambda函数,但是其中类通过重载operator()也可以像函数一样被调用,这就是被我们忽略的仿函数。百度百科定义为:使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为。
在stl中提供了大量有用的仿函数,比如plus,minus,multiplies,divides,modulus,equal_to,not_equal_to,greater…很多很多,根据传入的参数的个数我们可以分为只需要接受一个参数的仿函数(unary_function)和需要接收两个参数的仿函数(binary_function)。其源码实现基本类似:
template<class _Arg, class _Result> struct unary_function //只需要接受一个参数的仿函数,返回值类型为_Result { // base class for unary functions typedef _Arg argument_type; typedef _Result result_type; }; template<class _Arg1, class _Arg2, class _Result> struct binary_function //需要接受两个参数的仿函数,返回值类型为_Result { // base class for binary functions typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; };
比如 bit_not(按位取反)操作只需要接收一个参数:
template<class _Ty = void> struct bit_not : public unary_function<_Ty, _Ty> { // functor for unary operator~ _Ty operator()(const _Ty& _Left) const { // apply operator~ to operand return (~_Left); } };
比如最经典的我们在申明一个map时,其中map是一个需要3个泛型参数的类,其声明为
template<class _Kty, class _Ty, class _Pr = less<_Kty>, class _Alloc = allocator<pair<const _Kty, _Ty> > > class map..... //省略不重要代码
我们知道map是一个有序容器,那么到底是以如何的顺序呢?就在于第二个泛型参数
class _Pr = less<_Kty>,其默认值为
less<_Kty>,less是stl内置的用于两者比较大小的仿函数,也就是map是按照key由小到大的顺序排列的。less的实现源码如下:
template<class _Ty = void> struct less : public binary_function<_Ty, _Ty, bool> { // functor for operator< bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator< to operands return (_Left < _Right); } };
那么如果我们想把map的排列顺序改为由大到小,甚至建立自己的排序规则都只要依葫芦画瓢重写一个仿函数然后声明map时盖住默认的less行为即可。
STL大致分为六大模块:容器(container),算法(algorithm),迭代器(iterator),仿函数(functor),配接器(adapter),配置器(allocator)。其中仿函数是体积最小,观念最简单,但是在stl算法的搭配中起到了非常重要的作用,这是与简单的lambda或者指针函数所不同的。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性