仿函数
来源:互联网 发布:通话软件源码 编辑:程序博客网 时间:2024/04/29 08:57
所有的仿函数定义在头文件<functional>中。
1.定义及分析
仿函数就是一个定义了operator()的对象。
class X {public://define "function call" operatorreturn-value operator() (arguments) const;...};//现在这个类对象就可以当做函数一样使用X fo;...fo(arg1, arg2); //call operator () for function object fo//等同于fo.operator() (arg1,arg2); //调用对象fo的operator()
凡是行为像函数,那么这个对象就是函数。仿函数就是这个意思,但是STL中为什么要用仿函数而不直接用函数呢?
首先STL是一个有自己规则的框架,函数指针无法和STL其他组件搭配(配接器),产生更灵活的变化:
仿函数应当有能力被函数配接器修饰,然后彼此合作形成一个整体。为了可配接仿函数需要定义自己的相应型别(和迭代器的型别的作用是一个含义)。由于STL只使用一元和二元仿函数,所以定义了两个class:unaru_function和binary_function。这两个类没有成员,只有一些型别定义。任何仿函数,只要依个人需求选择继承其中一个class,便自动拥有了那些相应型别,也就自动拥有了配接能力。
其次仿函数相对于函数指针有其自身优点:
1、 仿函数是智能型函数
就好比智能指针的行为像指针,其就可看作是一个指针。但是智能指针是定义的一个类对象,所以在具备指针功能的同时也有其他的能力。仿函数的能力也可以超越operator()。因为仿函数可以拥有成员函数和成员变量,这意味着仿函数拥有状态。另一个好处是可以在执行期初始化它们。
class AddValue {private:int theValue; //the value to addpublic:AddValue(int v) : theValue(v) {}void operator() (int& elem) const {elem += theValue;}};AddValue addx (x); //+xAddValue addy (y); //+yAddValue(10))//常量AddValue (*coll. begin())//变量
2、 仿函数都有自己的型别
这就是泛型编程编写仿函数。
3、 仿函数通常比一般函数快
就template的概念而言,由于更多细节在编译器就已确定,所以通常可能进行更好的最佳化。
2.预定义的仿函数
2.1算术类
除了否定为一元,其他都为二元仿函数。
加法:plus<T>
减法:minus<T>
乘法:multiplies<T>
除法:divides<T>
求余:modulus<T>
否定:negate<T>
2.2关系运算类
都是二元仿函数。
等于:equal_to<T>
不等于:not_equal_to<T>
大于:greater<T>
大于等于:greater_equal<T>
小于:less<T>
小于等于:less_equal<T>
2.3逻辑运算类
与和或为二元仿函数,否为一元仿函数。
与:logical_and<T>
或:logical_or<T>
否:logical_not<T>
3.仿函数配接器
仿函数配接器是配接器(仿函数、容器、迭代器)中最大的一部分。主要运用到的如以下所示:
绑定第一个参数为定值:bind1st(op,x)——效果op(x,param)
绑定第二个参数为定值:bind2nd(op,x)——效果op(param,x)
对一元仿函数逻辑取反:not1(op)——效果!op(param)
对二元仿函数逻辑取反:not2(op)——效果!op(param1,param2)
SGI版本特有的还有compose1和compose2,就是组合函数的意思:
compose1(op1,op2)——效果op1(op2())
举例:
判定元素不小于12:bind2nd(greater_equal<int>(),12)或者not1(bind2nd(less<int>(),12))
对元素x执行(x+2)*3:compose1(bind2nd(multiplies<int>,3),bind2nd(plus<int>(),2))
另外的函数配接器就是针对成员函数而设计的函数配接器:
mem_fun_ref(op) 调用op,是某对象的一个const成员函数
men_fun(op) 调用op,是某对象指针的一个const成员函数
注意,被men_fun_ref和men_fun调用的成员函数必须是const,C++标准库暂时不支持non-const成员函数提供函数配接器。
class Person {private:std::string name;public:...void print() const {std::cout << name << std::endl;}void printWithPrefix (std::string prefix) const {std::cout << prefix << name << std::endl;}};void foo (const std::vector<Person>& coll){using std::for_each;using std::bind2nd;using std::mem_fun_ref;//对各个元素调用成员函数printfor_each (coll.begin(), coll.end(),mem_fun_ref(&Person::print));//对各个元素调用成员函数printWithPrefix//-"person: "是传递的一个参数,所以使用了bind2ndfor_each (coll.begin(), coll.end(),bind2nd (mem_fun_ref (&Person::printWithPrefix),"person: "));}
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- 仿函数
- asp.net网页里插入视频文件
- 《iOS网络编程与云端应用最佳实践》上线了
- HBase Split 过程
- 什么是表单库?
- 微信架构秘密
- 仿函数
- Spark standalone cluster模式部署实践
- VMware linux 增加根目录空间 (使用图形分区工具gparted LiveCd)
- Bt5 R3 播放mp3
- poj 2001 shortest prefix
- iOS多线程编程指南(二)线程管理
- hdu 2066 一个人的旅行(Dijkstra求最短路问题)
- 第39阶台阶 - 蓝桥杯
- java 空指针异常(java.lang.NullPointerException)