当前位置: 首页 > news >正文

C++仿函数以及STL内置仿函数

仿函数又称函数对象,本质是重载了operator()运算符的类的对象,可以和普通函数一样被调用。

一、仿函数基础概念

1. 什么是仿函数

仿函数不是函数,而是一个类类型的对象。当我们给这个对象加上()调用运算符时,它会触发类中重载的operator(),从而实现类似函数的行为。

最简单的仿函数示例

#include <iostream> using namespace std; // 定义仿函数类 struct Add { // 重载函数调用运算符 int operator()(int a, int b) const { return a + b; } }; int main() { Add add; // 创建仿函数对象 cout << add(3, 5) << endl; // 像函数一样调用,输出8 cout << Add()(10, 20) << endl; // 临时对象调用,输出30 return 0; }

2. 仿函数的核心优势(为什么不用普通函数?)

仿函数解决了普通函数和函数指针的诸多局限性,是 STL 首选的可调用对象形式:

特性普通函数函数指针仿函数
携带状态❌ 只能通过全局变量❌ 只能通过全局变量✅ 可以作为类成员变量存储状态
性能可内联❌ 间接调用,无法内联✅ 编译器可直接内联operator()
类型安全❌ 类型擦除,易出错✅ 每个仿函数都是独立类型
泛型支持✅ 完美适配模板元编程
可组合性✅ 可通过适配器灵活组合

3. 仿函数的分类

根据operator()接受的参数个数,仿函数分为:

  • 一元仿函数:接受 1 个参数,如negate<int>
  • 二元仿函数:接受 2 个参数,如plus<int>
  • 多元仿函数:C++11 后支持,但 STL 内置仿函数最多二元

二、STL 内置仿函数全解

STL 在<functional>头文件中提供了一套完整的通用仿函数,覆盖了所有基础运算,无需我们重复编写。它们都是模板类,可以适配任意数值类型。

1. 算术运算仿函数

用于执行基本的算术计算,全部是二元仿函数(除了negate是一元)。

仿函数功能等价表达式
plus<T>加法a + b
minus<T>减法a - b
multiplies<T>乘法a * b
divides<T>除法a / b
modulus<T>取模a % b
negate<T>取反(一元)-a

使用示例

#include <vector> #include <algorithm> #include <functional> using namespace std; int main() { vector<int> a = {1, 2, 3, 4}; vector<int> b = {10, 20, 30, 40}; vector<int> c(4); // 两个数组对应元素相加 transform(a.begin(), a.end(), b.begin(), c.begin(), plus<int>()); // c = {11, 22, 33, 44} // 所有元素取反 transform(a.begin(), a.end(), a.begin(), negate<int>()); // a = {-1, -2, -3, -4} return 0; }

2. 关系运算仿函数

用于比较两个值的大小关系,全部是二元仿函数,返回bool类型。

仿函数功能等价表达式
equal_to<T>等于a == b
not_equal_to<T>不等于a != b
less<T>小于a < b
greater<T>大于a > b
less_equal<T>小于等于a <= b
greater_equal<T>大于等于a >= b

高频使用场景

#include <vector> #include <algorithm> #include <functional> using namespace std; int main() { vector<int> v = {3, 1, 4, 1, 5, 9}; // 降序排序(默认是less<int>()升序) sort(v.begin(), v.end(), greater<int>()); // v = {9, 5, 4, 3, 1, 1} // 统计大于5的元素个数 int cnt = count_if(v.begin(), v.end(), bind(greater<int>(), placeholders::_1, 5)); // cnt = 1 return 0; }

⚠️面试重点std::sort默认使用less<T>(),实现升序排列;std::map/std::set默认也使用less<T>作为比较器,保证元素按升序存储。

3. 逻辑运算仿函数

用于执行布尔逻辑运算,返回bool类型。

仿函数功能等价表达式
logical_and<T>逻辑与a && b
logical_or<T>逻辑或`ab`
logical_not<T>逻辑非(一元)!a

使用示例

#include <vector> #include <algorithm> #include <functional> using namespace std; int main() { vector<int> v = {1, 6, 12, 18, 25}; // 查找大于5且小于20的第一个元素 auto it = find_if(v.begin(), v.end(), [](int x) { return logical_and<int>()(greater<int>()(x, 5), less<int>()(x, 20)); }); // it指向6 return 0; }

4. 位运算仿函数(C++11 新增)

用于执行整数的位运算。

仿函数功能等价表达式
bit_and<T>按位与a & b
bit_or<T>按位或`ab`
bit_xor<T>按位异或a ^ b
bit_not<T>按位取反(C++14)~a
http://www.jsqmd.com/news/946534/

相关文章:

  • 告别格式限制:QMCFLAC2MP3 让你真正拥有音乐自由
  • SX1262 LoRa模块功耗优化实战:从Standby模式到CAD侦听的省电配置全解析
  • CPU上卷积神经网络能效优化与算法选择
  • 从零到一:手把手教你用Vivado配置7系列FPGA的GTX收发器(以XC7K325T为例)
  • 告别Arduino IDE默认支持:手把手教你为冷门芯片ATmega168P烧录Bootloader(附USBasp实战)
  • Python为何成为TVA的神经与感官系统(5)
  • 不止于抓包:用mitmdump+Python脚本实现App请求自动修改与数据清洗
  • 如何在15分钟内完成Windows系统优化:WinUtil终极指南
  • 告别模型下载与部署,用快马平台ai服务直接提升你的代码开发效率
  • 0基础学挖漏洞,从入门到实战,这一篇保姆级教程就够了!
  • 终极指南:用OpenCore Legacy Patcher让旧Mac运行最新macOS的完整教程
  • 混合精度训练O2模式深度测评:Faster Mask RCNN在昇腾NPU上的精度与速度平衡
  • 日语重排序模型对比分析:为什么选择japanese-reranker-cross-encoder-small-v1
  • 10分钟掌握Illustrator智能填充:Fillinger插件完整解决方案
  • LLM代理系统安全威胁:隐式毒性攻击与防御策略
  • Gemma 4本地Agent落地指南:从能跑到能用的四层确定性设计
  • 微信支付出海、宁德超充、Kimi K2.6落地实战指南
  • 业务落地AI的三道硬门槛:数据、流程与权责
  • 别扔!用全志A13山寨平板打造你的专属Linux服务器(附Ubuntu 18.04镜像)
  • Python为何成为TVA的神经与感官系统(6)
  • GPT-5.5+具身智能:保险理赔流程重铸的临界点
  • 别再只画二维图了!用Matplotlib的Axes3D给你的K-means聚类结果做个酷炫三维体检
  • 【仅开放72小时】AI秒杀整合SOP白皮书V3.2:含12个生产环境故障快照、4类GPU资源争抢日志分析、1套AB测试评估矩阵
  • 从“亚太2R”到“星链”:卫星天线调星原理简史与家用卫星网络入门指南
  • 秩基半参数拟似然协方差估计方法解析与应用
  • 终极指南:5步让老旧Mac重获新生,运行最新macOS系统
  • 别再手动写C接口了!用Simulink Coder把模型一键打包成DLL(附VS2015配置避坑)
  • ABB机器人PC SDK避坑指南:从Visual Studio 2019环境配置到成功建立TCP/IP连接的全记录
  • 2026年知名的越南监控安装/越南监控维修/越南监控维护/越南监控改造排行榜 - 行业平台推荐
  • Windows终极优化神器WinUtil:一站式解决系统安装、优化与配置难题