信息发布→ 登录 注册 退出

C++ ptr_fun与mem_fun的区别_C++函数适配器的历史与替代方案

发布时间:2025-11-26

点击量:
ptr_fun用于包装普通函数指针,mem_fun用于包装成员函数指针,二者均为早期STL适配器;2. 因语法繁琐且功能受限,自C++11起被lambda、std::function和std::bind取代;3. C++17中正式移除,现代代码应使用lambda或bind替代。

c++ ptr_fun与mem_fun的区别_c++函数适配器的历史与替代方案

在C++标准库中,ptr_funmem_fun 是早期用于适配函数指针和成员函数指针的函数适配器,主要用于配合STL算法使用。随着语言的发展,它们逐渐被更现代、更灵活的机制取代。理解它们的区别以及为何被淘汰,有助于掌握C++函数对象演进的历史脉络。

ptr_fun:普通函数指针的包装器

ptr_fun 用于将普通函数指针转换为函数对象(functor),以便能被STL算法接受。某些老式STL实现要求函数对象具有特定的类型特征(如result_type),而裸函数指针不具备这些typedef,因此需要包装。

示例:

假设有函数:
bool is_even(int n) { return n % 2 == 0; }
在旧式代码中,要传递给std::not1等适配器时需包装:
std::ptr_fun(is_even)
这会生成一个带类型定义的函数对象,支持绑定与取反操作。

mem_fun:成员函数的适配器

mem_fun 专门用于包装类的成员函数指针,使其能通过对象指针调用。常用于std::for_eachstd::transform等算法中对容器中对象指针调用成员函数。

示例:

对于类:
class Task { public: void run(); };
容器为std::vector<task></task>时,可使用:
std::for_each(tasks.begin(), tasks.end(), std::mem_fun(&Task::run));
它会自动解指针并调用成员函数。

C++还提供mem_fun_ref用于对象引用的场景,适用于存储实际对象而非指针的容器。

历史局限与替代方案

上述适配器在C++98/03时代是必要的,但存在明显缺陷:

美图云修 美图云修

商业级AI影像处理工具

美图云修 50 查看详情 美图云修
  • 语法繁琐,需显式指定模板参数或依赖重载解析
  • 不支持任意可调用对象(如仿函数、lambda)
  • 对参数数量敏感,有mem_funmem_fun1等变体

从C++11开始,以下现代机制全面替代了它们:

  • Lambda表达式:最直接的方式,可捕获上下文并内联定义逻辑
  • std::function:统一封装任意可调用对象
  • std::bind:灵活绑定函数与参数,包括成员函数
  • 自动类型推导(auto):简化函数对象的使用

现代替代示例:

用lambda调用成员函数:
std::for_each(tasks.begin(), tasks.end(), [](Task* t) { t->run(); });
或使用bind:
std::for_each(tasks.begin(), tasks.end(), std::bind(&Task::run, std::placeholders::_1));

在C++17中,ptr_funmem_fun 已被正式移除。编译器虽可能仍支持出于兼容性考虑,但不应再使用。

基本上就这些。老式适配器是特定历史阶段的产物,理解它们有助于阅读旧代码,但在新项目中应优先使用lambda和std::bind。

以上就是C++ ptr_fun与mem_fun的区别_C++函数适配器的历史与替代方案的详细内容,更多请关注其它相关文章!


相关文章: C++ explicit关键字防止隐式转换_C++构造函数安全规范  中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】  NVIDIA股价11月重挫12%:下月有望好转 但难回5万亿美元巅峰  知音漫客正版漫画平台_知音漫客官网账号登录  处理动态列数据:J*a ArrayList的正确初始化与字符累加教程  Go语言中构建可靠数据存储的原子性与持久化策略  J*a实现学校排课程序_面向对象结构化项目示例  J*aScript中赋值与自增运算符的复杂交互与执行机制  知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法  解决Flask中Quill编辑器内容提交失败及TypeError的指南  在J*a中如何使用ForkJoinPool进行分治任务并行处理_ForkJoinPool分治并行技巧说明  c++ dfs和bfs代码 c++深度广度优先搜索算法  优化Lar*el Docker镜像:Composer与PHP版本控制策略  AO3最新可访问网址 Archive of Our Own官方在线入口  C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略  J*aScript map 迭代中检测空数组元素的有效方法  天眼查企业查询官网入口 天眼查官方网页版查询  微信网页版官方入口直达 微信网页版网页版登录使用方法  Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略  J*aScript中如何高效提取对象指定属性  必由学官方登录入口 必由学教师学生账号快速访问  德邦快递查询平台 德邦快递物流信息查询入口  QQ邮箱官网登录入口 QQ邮箱网页版邮箱快速登录  Basecamp怎样用留言钉固定重点_Basecamp用留言钉固定重点【重点标记】  谷歌google账号注册详细步骤 谷歌账号注册官方教程  taptap防沉迷怎么解除 taptap解除健康系统限制说明【2025最新】  mysql如何分析事务日志_mysql事务日志分析方法  Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑  Angular响应式表单:实现提交后表单及按钮的禁用与只读化  PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误  Yandex官网免登录入口_俄罗斯Yandex搜索引擎一键访问  Go语言中高效处理x-www-form-urlencoded表单数据  顺丰快递查单号物流信息 顺丰快递小程序查询入口  如何在J*a中使用Locale处理多语言环境  uc浏览器网页版极速入口 uc网页浏览器网页版流畅体验  Windows10怎么开启存储感知 Windows10系统设置自动清理临时文件释放C盘空间【教程】  深入理解与实现最大堆的Heapify过程:常见错误与修正  Win10怎么制作U盘启动盘 Win10系统安装U盘制作教程【详解】  Word2013如何插入视频和音频媒体_Word2013媒体插入的多媒体支持  windows10怎么关闭系统提示音_windows10彻底静音设置方法  在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南  优化Django表单:提交验证失败后保留用户输入  c++如何使用chrono库处理时间_c++标准库时间与日期操作  夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案  Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践  Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换  俄罗斯浏览器官网直达链接 俄罗斯浏览器最新在线入口导航  163邮箱官方主页登录 直达网易邮箱登录核心页面  快速CSGO开箱网站指南 CSGO开箱平台推荐  顺丰国际快递查询 国际件官方查询入口 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!