24. 函数符
函数对象函数对象函数符 functor函数对象也叫函数符functor是可以以函数方式与 () 结合使用的任意对象。这包括函数名、指向函数的指针以及重载了 () 运算符的类对象即定义了 operator()() 的类。例如定义一个 Linear 类重载的 () 运算符使得能够像函数那样使用 Linear 对象f1(12.5) 的右侧就是 f1.operator()(12.5)。class Linear { // 函数符类重载 () 运算符 private: double slope; // 斜率由构造函数设置 double y0; // 截距由构造函数设置 public: Linear(double sl, double y) // 构造函数绑定状态 : slope(sl), y0(y) {} double operator()(double x) { // 重载 ()使对象可像函数调用 return y0 slope * x; // x 来自调用参数 } }; // Linear f1(1.0, 0.0); double y1 f1(12.5); // 计算 0 1*12.5for_each 的第三个参数与模板机制for_each 本质上就是一个“包装好的 for 循环”它负责从头到尾遍历容器并把每个元素依次传递给你提供的函数或函数对象去执行。for_each() 的第三个参数可以是常规函数也可以是函数符。for_each( 起始位置, 结束位置, 函数/对象 );不能把它声明为函数指针因为函数指针指定了参数类型由于容器可以包含任意类型预先无法知道应使用哪种参数类型。STL 通过使用模板解决这个问题其原型为template class InputIterator, class Function Function for_each(InputIterator first, InputIterator last, Function f);// for_each 的原型Function 可为函数指针或函数符类 template class InputIterator, class Function Function for_each(InputIterator first, InputIterator last, Function f) { while (first ! last) { // 遍历整个区间 f(*first); // 对每个元素调用 f first; } return f; // 返回函数对象 }函数符概念generator / unary / binary / predicate函数符概念Generator / Unary / Predicate是 STL 算法对“传入参数个数”和“返回值类型”的一种“硬性接口约定”。生成器generator是不用参数就可以调用的函数符一元函数unary function是用一个参数可以调用的函数符二元函数binary function是用两个参数可以调用的函数符谓词predicate是返回 bool 值的一元函数二元谓词binary predicate是返回 bool 值的二元函数。如 for_each() 的函数符应当是一元函数因为它每次用于一个容器元素一些 STL 函数需要谓词参数或二元谓词参数。remove_if 与类函数符传递额外信息形态用法是否真的释放内存改变容器大小后续必须做的事通用算法头文件algorithmstd::remove_if(v.begin(), v.end(), pred)❌否。它只是把“被删的元素”挪到末尾把“保留的元素”挪到前面容器大小不变。必须配合erase()才能真正删除即Erase-Remove 惯用法。list成员函数头文件listmy_list.remove_if(pred)✅是。链表节点被直接销毁list的大小自动变小。不需要任何后续操作。算法限制remove_if 只能接受一元谓词一个参数用于接收当前遍历到的元素。信息瓶颈普通函数只能写死阈值无法动态传入第二个参数。解决方法函数符利用类成员变量如 cutoff携带“额外信息”。构造函数负责设置规则operator() 负责结合元素和规则做出判断。template class T class TooBig { // 类函数符用成员携带额外信息 private: T cutoff; // 取舍值由构造函数设置 public: TooBig(const T t) : cutoff(t) {} // 构造函数绑定阈值 bool operator()(const T v) { // 谓词单个参数 return v cutoff; // 判断是否大于阈值 } }; // scores.remove_if(TooBigint(200)); // 删除所有大于 200 的元素类函数符作为函数适配器TooBig2如果已经有一个接受两个参数的模板函数 tooBig(val, lim)可以用类将它转换为单参数的函数对象——TooBig2 类把第二个参数用于构建函数对象operator() 内部调用二元模板函数并传入已绑定的 cutoff。template class T bool tooBig(const T val, const T lim) { // 已有的二元模板函数 return val lim; } ​ template class T class TooBig2 { // 函数适配器二元→一元 private: T cutoff; // 绑定的第二个参数 public: TooBig2(const T t) : cutoff(t) {} bool operator()(const T v) { // 单参数接口 return tooBigT(v, cutoff); // 内部调用二元函数 } }; // TooBig2int tB100(100); if (tB100(x)) // 等价于 if (tooBig(x, 100))transform() 算法transform() 算法用于对一个或两个输入区间中的每个元素执行指定操作并将计算结果写入目标区间实现“批量转换”。一元将一个区间中的每个元素通过一元函数op转换输出到另一个区间。template class InputIt, class OutputIt, class UnaryOp OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOp op);参数含义first1, last1输入区间的起点和终点d_first目标区间的起点输出结果op一元函数符接收一个元素返回转换后的值#include algorithm #include vector ​ std::vectorint src {1, 2, 3, 4}; std::vectorint dst(4); // 预留空间 ​ // 把 src 中的每个元素平方存入 dst std::transform(src.begin(), src.end(), dst.begin(), [](int x) { return x * x; }); // dst 变为 {1, 4, 9, 16}二元版将两个区间中对应位置的元素通过二元函数 binary_op 结合输出到目标区间。template class InputIt1, class InputIt2, class OutputIt, class BinaryOp OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOp binary_op);参数含义first1, last1第一个输入区间的起点和终点first2第二个输入区间的起点长度由第一个区间决定d_first目标区间的起点binary_op二元函数符接收两个元素返回结合后的值std::vectorint a {1, 2, 3}; std::vectorint b {10, 20, 30}; std::vectorint result(3); ​ // 把 a 和 b 的对应元素相加存入 result std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](int x, int y) { return x y; }); // result 变为 {11, 22, 33}注意第二个输入区间必须至少有 last1 - first1 个元素否则行为未定义。目标迭代器可以等于输入迭代器实现“原地修改”。预定义的函数符头文件 functional预定义函数符是“运算符的‘函数对象’包装器”。因为STL 算法的参数是“对象”而不是“符号”。分类函数符名称对应的运算符中文含义算术plusT加法minusT-减法multipliesT*乘法dividesT/除法modulusT%取模余数negateT-一元取负如-5比较关系equal_toT等于not_equal_toT!不等于greaterT大于lessT小于greater_equalT大于等于less_equalT小于等于逻辑logical_andT逻辑与logical_orT||逻辑或logical_notT!逻辑非自适应函数符adaptable functor与函数适配器STL 有 5 个相关概念自适应生成器adaptable generator、自适应一元函数adaptable unary function、自适应二元函数adaptable binary function、自适应谓词adaptable predicate和自适应二元谓词adaptable binary predicate。使函数符成为自适应的原因是它携带了标识参数类型和返回类型的 typedef 成员result_type、first_argument_type和second_argument_type如plusint对象的返回类型被标识为plusint::result_type。binder1st它的数学本质是“固定二元函数的一个参数把它变成一元函数。”它把2.5“绑定”到multiplies的第一个参数上生成一个新的临时对象。这个新对象只需要接收一个参数x内部执行2.5 * x。现代 CC11 起中它已经被 Lambda 表达式和 std::bind 彻底取代了。知识点描述函数对象函数符可以函数方式与()结合使用的对象函数名、函数指针、重载()的类对象类函数符用构造函数保存状态x来自operator()参数。for_each 第三参数与模板第三参数不能声明为函数指针参数类型不确定用模板参数Function同时接受函数指针与函数符类for_each内部用f()统一调用。函数符概念生成器无参数、一元函数一个参数、二元函数两个参数、谓词返回 bool 的一元函数、二元谓词返回 bool 的二元函数for_each需要一元函数。remove_if 与类函数符list::remove_if(predicate)对每个元素应用谓词返回 true 则删除谓词只能一个参数用类成员构造函数设置 cutoff传递额外信息。类函数符作为函数适配器用类把二元模板函数转换为单参数函数对象第二参数由构造函数绑定、operator()内部调用二元函数TooBig2是函数适配器使函数满足不同接口。transform() 算法一元版对区间每元素施加函数符生成新序列二元版对两个区间对应元素施加二元函数目标迭代器可在原区间内覆盖旧值。预定义的函数符functional提供与内置算术/关系/逻辑运算符等价的函数符plus、multiplies、greater 等因运算符不是函数用plusdouble()等作为算法参数老式实现用times代替multiplies。自适应函数符与函数适配器自适应函数符携带result_type、first_argument_type、second_argument_typetypedefbinder1st/binder2nd将自适应二元函数适配为一元绑定第一/第二参数助手函数bind1st()/bind2nd()简化创建。

相关新闻

Vue4.0:开发进度、核心升级与未来特性全景解析

Vue4.0:开发进度、核心升级与未来特性全景解析

本文基于 2026 Vue&ViteConf 官方官宣,精准解答:Vue4.0 是否真的启动开发、和 Vue3.6 的关系、核心革命性升级、开发者最值得期待的特性,同时破除网络谣言,适配面试、技术选型、前端进阶学习。一、核心答案:Vue4.0…

2026/10/11 23:09:15 阅读更多 →
23.泛型编程下

23.泛型编程下

复杂度(complexity) 复杂度描述了执行操作所需的时间,有三种可能性,从快到慢依次为: 编译时间(compile time):操作在编译时执行,执行时间为 0; 固定时间&am…

2026/10/8 1:03:23 阅读更多 →
苹果ASA广告只显示文字、不展示图片问题详解

苹果ASA广告只显示文字、不展示图片问题详解

很多开发者和投放客户都会遇到同一个疑惑:苹果搜索广告(ASA)时而展示带APP截图的图片版广告,时而只显示图标和文字,没有任何图片素材。大家普遍误以为是账号故障、素材失效、投放出错,其实这是苹果官方固定…

2026/10/5 14:35:21 阅读更多 →

最新新闻

Java面向对象编程与泛型实战解析

Java面向对象编程与泛型实战解析

1. 面向对象编程核心概念解析面向对象编程(OOP)是Java语言的基石,理解其核心概念对开发者至关重要。在实际项目开发中,我发现很多初级开发者虽然能背诵OOP的四大特性(封装、继承、多态、抽象),但…

2026/10/13 8:40:58 阅读更多 →
储能调峰配置与经济性分析:Matlab复现实战指南

储能调峰配置与经济性分析:Matlab复现实战指南

最近在做一个“参与调峰的储能系统配置方案及经济性分析”的EI复现项目,目标很明确:把一篇储能调峰领域的经济性优化文献,用Matlab从模型到仿真完整跑通。所谓EI复现,不是拿别人现成代码跑一遍那么简单,而是根据论文里…

2026/10/13 8:40:58 阅读更多 →
GaussDB(for PostgreSQL)入门实战:从建库建表到SQL操作与避坑指南

GaussDB(for PostgreSQL)入门实战:从建库建表到SQL操作与避坑指南

前一阵因为一个模拟项目X需要搭一套数据库环境,明确要求兼容PostgreSQL生态、能免去自建主从和高可用运维负担,我就把目标放在了某云厂商的GaussDB(for PostgreSQL)上。起初我以为这就是个“带分布式外衣的PG”,真正上手才发现,它…

2026/10/13 8:40:58 阅读更多 →
免费IP库实战:从数据清洗到本地查询服务搭建

免费IP库实战:从数据清洗到本地查询服务搭建

给日志分析系统加过IP归属地解析的兄弟,应该都懂这种体验:调在线接口查一次IP,速度快慢先不说,账单涨得比日志涨得还快。尤其流量稍大一些,按次计费的第三方接口根本经不起用。所以我一直觉得,“免费好用的…

2026/10/13 8:40:58 阅读更多 →
乒乓球拾球机器人机械结构设计:滚刷参数、电机选型与装配避坑全解

乒乓球拾球机器人机械结构设计:滚刷参数、电机选型与装配避坑全解

简介:这份PDF资料围绕自动拾取乒乓球机器人的机械结构设计展开,面向机器人工程、机械设计与自动化专业的师生及研究人员,聚焦乒乓球训练场景中捡球、送球环节的自动化需求。内容涵盖总体方案设计、轮式行走系统、微型真空泵捡球机构、平面四连…

2026/10/13 8:40:58 阅读更多 →
Agent技能拆解与编排实战:从碎片化到体系化

Agent技能拆解与编排实战:从碎片化到体系化

1. 技能碎片化:Agent落地的头号瓶颈这段时间在折腾智能体项目,我最大的体会就是:真正卡住进度的往往不是模型选型,不是推理框架,而是“技能”这层皮。模型再聪明,碰到实际任务时还是靠一个个具体技能去接活…

2026/10/13 8:39:55 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →