如果有一个函数f和一个对象x,现在希望在x上调用f,而我们在x的成员函数之外,执行这个调用,C++提供了三种方法:

  • f(x); // 语法1 f是一个非成员函数
  • x.f();// 语法2 f时成员函数,x是一个对象或对象的引用
  • p->f(); // 语法3 f是成员函数,p是一个对象指针

有一个用于测试Widget对象的函数Test和一个存放Widget的容器datas:

void Test(Widget& w);
std::vector<Widget> datas;

为了测试datas中的每一个对象,可以使用如下方式来调用for_each

std::for_each(datas.begin(), datas.end(), Test); // 调用方式1

假设Test是Widget的成员函数:

class Widget
{public:...void Test();...
}

也应该可以使用for_each在datas中的每个对象上调用Widget::Test():

std::for_each(datas.begin(), datas.end(), &Widget::Test); // 调用方式2

如果datas中保存的是Widget*指针,也应该可以使用for_each来调用Widget::Test():

std::vector<Widget*> datas;
std::for_each(datas.begin(), datas.end(), &Widget::Test); // 调用方式3
在这里插入代码片

实际情况是:调用方式1成功,调用方式2、调用方式3都失败。

先看下for_each算法的实现:

template<typename InputInterator, typename Function>
Function for_each(InputIterator begin, InputIterator end, Function f)
{while (begin != end) f(*begin++);
}

调用1完成符合for_each内部的调用方式。调用方式2、调用方式3都不符合。

那调用方式2、调用方式3如何修改?
分别使用mem_fun_ref和mem_funmem_func用来指针类型上,其他的使用mem_func_refmem_funmem_func_ref内部可以将调用方式2、调用方式3都转换成调用方式1,内部涉及到函数对象配接器。

std::vector<Widget> datas;
std::for_each(datas.begin(), datas.end(), mem_func_ref(&Widget::Test)); // 调用方式2 正确调用方式

如果datas中保存的是Widget*指针,也应该可以使用for_each来调用Widget::Test():

std::vector<Widget*> datas;
std::for_each(datas.begin(), datas.end(), mem_func(&Widget::Test)); // 调用方式3 正确调用方式
在这里插入代码片

41. 理解ptr_fun、mem_fun和mem_fun_ref的来由相关推荐

  1. STL中mem_fun与mem_fun_ref的区别[转]

    STL中mem_fun和mem_fun_ref的用法 分类: C++2006-11-21 09:11 5244人阅读 评论(8) 收藏 举报 怎么对容器中的所有对象都进行同一个操作?我们可能首先想到的 ...

  2. 读书笔记 effective c++ Item 41 理解隐式接口和编译期多态

    1. 显示接口和运行时多态 面向对象编程的世界围绕着显式接口和运行时多态.举个例子,考虑下面的类(无意义的类), 1 class Widget { 2 public: 3 Widget(); 4 vi ...

  3. Effective STL 50条有效使用STL的经验笔记

    Scott Meyers大师Effective三部曲:Effective C++.More Effective C++.Effective STL,这三本书出版已很多年,后来又出版了Effective ...

  4. C++ 容器及选用总结

    原文地址 目录 ==================================================== 第一章 容器 第二章 Vector和string 第三章 关联容器 第四章 迭 ...

  5. 《Effective STL》条款解读

    条款01:慎重选择容器类型 vector.list和deque有着不同的复杂度,vector是默认使用的序列类型.当需要频繁在序列中间做插入和删除操作时,应使用list.当大多数插入和删除操作发生在序 ...

  6. Effective STL中文版:50条有效使用STL的经验(双色)

    <Effective STL中文版:50条有效使用STL的经验(双色)> 基本信息 作者: (美)梅耶(Meyers,S.) 译者: 潘爱民 陈铭 邹开红 出版社:电子工业出版社 ISBN ...

  7. 《Effective STL》重读笔记整理

    最近有闲,在工作之余重读了<effective STL>一书,并通过 twitter 记了一下笔记,今天整理收集到这里. twitter 真的非常适合记读书笔记,哈哈,以后要好好地发扬.另 ...

  8. c++容器使用50条总结

    第1章 容器 第1条:慎重选择容器类型. 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容 ...

  9. 【C++】Effective STL:50条有效使用STL的经验

    第一条:慎重选择容器类型 1.C++容器:先混个眼熟 序列容器:array.vector.string.deque.list.forward_list 有序关联容器:set.map.multiset. ...

  10. Effective STL 读书笔记

    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

最新文章

  1. linux java 替换jre_Linux系统 无需JRE配置Java
  2. 行家来信 | 我在国际AI开源组织LFAI当董事的200天
  3. 数据传输流程和socket简单操作
  4. Linux下使用PPTP ×××拔号的实现
  5. hashmap 判断key是否存在
  6. SpringBoot入门到精通_第1篇 _核心概念
  7. 统计一行文本的单词个数_LeetCode68-文本左右对齐
  8. 4月第3周业务风控关注 | 文化部再次审查直播和游戏产品,已下架4939款直播应用...
  9. mysql InnoDB 行锁分析
  10. JAVA排序:快速排序算法
  11. win10计算机变成了英文,Win10系统中自带的Office(Word,Excel)突然变成英文怎么变回中文...
  12. 总结oninput、onchange与onpropertychange事件的用法和区别
  13. OSPF 单区域配置实例学习记录
  14. 读书:《有无之境:王阳明哲学的精神》
  15. 怎么更改苹果账户名称_苹果新品快来了,你真的学会如何找回你的Apple ID的密码了吗?...
  16. python通过经纬度获取地址信息
  17. 工作感悟之Android系统开发入门
  18. Java练手项目2:基于Java的坦克大战游戏(学习Java必备!!!)
  19. java计算机毕业设计Vue垃圾分类指南平台设计与实现源码+mysql数据库+系统+lw文档+部署
  20. (4)雅思屠鸭第四天:六种简单句的练习与两种从句的讲解

热门文章

  1. BIO、NIO、AIO差别
  2. 热烈庆祝blog开通
  3. JDBC在Java Web中的应用——分页查询
  4. jQuery直接调用asp.net后台WebMethod方法
  5. idea tomcat 发布web工程全过程
  6. 6.高性能MySQL --- 查询性能优化(1)
  7. 63. 无阻塞加载脚本
  8. 20. PHP 表单验证 - 验证 E-mail 和 URL
  9. 对比AppScan Source和Fortify扫描AltoroJ的结果
  10. 章节十一、9-操作隐藏元素