仿函数,也称函数对象, 其实就是重载了括号运算符()的对象, 不过可以具有函数的一些性质, 可以在需要函数的地方(主要是各种容器和算法)使用.
一,仿函数的优点:
1,可以拥有状态, 可以在运行时动态地改变行为
3,速度更快, (其实快不了多少)
二,性质及应用
1, 主要应用在map等容器的构造函数和各种STL算法上
2,默认情况下是传值引用的, 也就是说仿函数的状态不会因算法而改变
3,如果需要传引用 需要显示声明,例如:
generate_n(back_inserter(coll),4,functor); //传值
generate_n<back_insert_iterator<list<int> >,int,Functor& >(back_inserter(coll),4,functor) //传引用
4,for_each算法可以返回仿函数,所以无需这么麻烦
5, C++预定义了几种仿函数,包括 加减乘除,取模, >,<, <=, >=, ==,!=, 逻辑或,且,非, 所有容器或算法默认的仿函数都是小于 less<type>
三,函数配接器
函数配接器用来组合各种仿函数, 通过一系列复杂的语法,你可以获得如下能力:
1,获得不同参数的仿函数
2,使仿函数体现出不同的性质,如相反等
3,组合多个仿函数
4,将类成员函数包装成仿函数
5,将普通函数包装秤仿函数
事实上, 函数配接器的功能都可以通过写一个函数来实现, 而函数配接器过于复杂,会使代码晦涩难懂,并且很可能因为其复杂的性质引入莫名其妙的错误
写一个简单直接的实现往往比那些看似功能更强大,更通用的实现更为有效, 搞定产品的需求才是码农的工作,代码上的奇思妙想只是业余爱好
四,运算符重载
C++提供了功能非常多的运算符重载功能,仿函数本身是一个括号运算符重载, 但这些重载更多地是被基础类库的编写者所用,对于普通码农一般用的不多
1, 重载运算符只需要保证参数的数量与内置操作符一致, 对于参数类型, 传引用/传值, const与否不做要求.
2, 运算符的优先级是固定的,并且重载后可能不再具备短路求值等特性
3,,运算符可以重载为类成员函数或普通函数, 一般来说,返回一个新值的运算符,例如加法运算符+,通常定义为普通函数, 返回本身引用的运算符,例如 +=,通常定义为成员函数. 赋值运算符只能定义为成员函数.
4,如果定义为普通函数, 而且运算符又需要访问私有成员, 需要在类中声明为友元函数. 典型的如输入运算符>>和输出运算符<<
5,关系运算符: 定义了一个运算符并不能自动扩展为与之关联的其他运算符,例如你定义了小于<, 还是不能使用>或>=.