二、仿函数
二、仿函数1定义2实例3仿函数的作用3.1**状态封装有状态**3.2**类型安全模板友好**4与函数的对比1定义什么是仿函数Functor从字面意思可以猜测是模仿函数的行为使其像函数一样被调用。具体的定义仿函数Functor是 C 中一种特殊的对象它通过重载operator()使得对象可以像函数一样被调用。仿函数本质上是类或结构体的实例但提供了函数调用的语法。2实例比如说我们想实现两个整数相加的功能直接使用加法函数返回结果即可。而当我们想要使用仿函数时需要重载operator()实例化出有名对象这样调用时就可以模仿函数的调用过程了。intAdd(intx,inty){returnxy;}structFunc_Add{intoperator()(inta,intb)const{returnab;}};intmain(){//Add函数coutAdd(1,2)endl;//仿函数//创建仿函数对象Func_Add f1;coutf1(1,2)endl;return0;}3仿函数的作用在看完上面的例子后会发现仿函数似乎使用起来比真正的函数还要麻烦为什么要创造出仿函数呢或者说仿函数的优点是什么3.1状态封装有状态仿函数可通过成员变量保存调用间的状态structCounter{intcount0;voidoperator()(){count;}};intmain(){Counter c;//初始c.count 0coutc.countendl;c();c();//c.count 2coutc.countendl;return0;}3.2类型安全模板友好在 C 中仿函数可以直接作为模板参数传递这是其最重要的优势之一。与函数指针不同仿函数是一个具体的类型模板可以根据该类型实例化出对应的版本编译器因此能够进行完全的内联优化生成更高效的代码。而传递函数指针时类型信息被擦除为指针类型往往难以内联还可能引入额外的间接调用开销。#includeiostream#includevector#includealgorithm// 仿函数按绝对值大小比较structAbsCompare{booloperator()(inta,intb)const{returnabs(a)abs(b);}};intmain(){std::vectorintv{3,-1,2,-5,4};// 直接将仿函数类型传递给模板编译器能生成针对 AbsCompare 的特化版本sort(v.begin(),v.end(),AbsCompare());// 输出-1 2 3 4 -5for(intx:v){coutx ;}return0;}4与函数的对比特性普通函数仿函数状态无状态只能通过全局/静态变量保存额外信息有状态可通过成员变量在调用间保存数据内联优化函数指针传递时难以内联直接调用可内联作为模板参数时类型确定极易内联模板参数传递必须退化为函数指针类型信息被擦除保留完整类型模板可生成专属实例多态/扩展性只能靠重载不能携带额外上下文可通过继承实现运行时多态配合虚函数也可组合多个仿函数语法简洁性定义简单调用自然需定义类并重载operator()稍显繁琐C11 lambda 为此提供了语法糖典型应用简单固定功能的操作自定义排序准则、状态回调、函数对象适配器等