本系列文章的目录在这里:目录. 通过目录里可以对STL总体有个大概了解

前言

本文总结了STL中函数适配器:mem_fn系列函数的用法,它们是:mem_fun (c++98), mem_fun_ref (c++98), mem_fn (c++11). 文中给出了它们各自的使用范围及代码示例,提到了mem_fn的使用限制,使用bind来解决这个限制。

基本用法

从名字也能看出个大概,mem_fn里面的mem就是指类的成员member, 而fn就是指function, 加在一起就是说member function,即mem_fn是用来适配类的成员函数的,下面从代码里来看一下它们的区别:

mem_fn_and_mem_fun.cpp是我写的一个测试文件,从注释里看,并列的3个部分,分别是:
1. mem_fun
2. mem_fun_ref
3. mem_fn

#include "gtest/gtest.h"
#include "inc.h"
#include <functional>
#include <algorithm>NS_BEGIN(elloop);using namespace std;
using namespace std::placeholders;// 定义一个类Foo用来测试,适配其成员函数
// 其中函数pln(x)是输出x,并换行的意思;
class Foo
{
public:// 无参数member functionvoid print() { pln(a_); }   // 接受一个参数的member functionvoid print2(int i) {pln(a_);pln(i);}int a_{ 100 };
};//----------------------- c++98 mem_fun and c++11 mem_fn -----------------------
BEGIN_TEST(FunctorTest, Mem_FunTest, @);// 1. mem_fun is for a pointer to an obj.
// 定义一个容器,存入几个Foo*, 然后使用mem_fun来取指针并绑定到Foo的成员函数
vector<Foo*> fpv;
fpv.push_back(new Foo());
fpv.push_back(new Foo());
fpv.push_back(new Foo());
fpv.push_back(new Foo());for_each(fpv.begin(), fpv.end(), mem_fun(&Foo::print));
cr;// mem_fun_ref用来绑定的target应该为Foo对象,而不是指针
//for_each(fpv.begin(), fpv.end(), mem_fun_ref(&Foo::print));   // error. for_each(fpv.begin(), fpv.end(), bind(&Foo::print, _1));    // also can use bind
cr;// 如果成员函数接受额外参数(不仅仅是对象本身), 那么mem_fun就无能为力了,要用bind
//for_each(fpv.begin(), fpv.end(), mem_fun(&Foo::print2, 10));
for_each(fpv.begin(), fpv.end(), bind(&Foo::print2, _1, 10)); // must use bind// 2. mem_fun_ref is for obj.
vector<Foo> fv;
fv.push_back(Foo());
fv.push_back(Foo());
fv.push_back(Foo());
fv.push_back(Foo());for_each(fv.begin(), fv.end(), mem_fun_ref(&Foo::print));
cr;// mem_fun 不能用来绑定对象.
// for_each(fv.begin(), fv.end(), mem_fun(&Foo::print));    // error.for_each(fv.begin(), fv.end(), bind(&Foo::print, _1));      // bind也可以
cr;// 如果成员函数接受额外参数(不仅仅是对象本身), 那么mem_fun就无能为力了,要用bind
//for_each(fv.begin(), fv.end(), mem_fun_ref(&Foo::print2, 10));for_each(fv.begin(), fv.end(), bind(&Foo::print2, _1, 10)); // bind可以有很多参数// 3. mem_fn既可以用于指针、引用,还可以用于对象本身,因此在C++11中使用mem_fn可以替代mem_fun和mem_fun_ref.
for_each(fpv.begin(),   fpv.end(),  mem_fn(&Foo::print));       // ptr
for_each(fv.begin(), fv.end(), mem_fn(&Foo::print));            // obj//for_each(fv.begin(), fv.end(), mem_fn(&Foo::print2, 10));
for_each(fv.begin(), fv.end(), bind(&Foo::print2, _1, 10)); //must use bindFoo foo;
Foo &foo_ref = foo;
mem_fn(&Foo::print)(foo_ref);                                   // ref// clear pointers.
for_each(fpv.begin(), fpv.end(), [&](Foo* foo)
{delete foo;foo = nullptr;
});END_TEST;NS_END(elloop);

总结

函数 作用
mem_fun 把成员函数转为函数对象,使用对象指针进行绑定
mem_fun_ref 把成员函数转为函数对象,使用对象(引用)进行绑定
mem_fn 把成员函数转为函数对象,使用对象指针或对象(引用)进行绑定
bind 包括但不限于mem_fn的功能,更为通用的解决方案,详见目录里std::bind的文章

源码及参考链接

  • 源码:mem_fn_and_mem_fun.cpp

  • mem_fun

  • mem_fun_ref

  • mem_fn


作者水平有限,对相关知识的理解和总结难免有错误,还望给予指正,非常感谢!

欢迎访问github博客,与本站同步更新

【C++ STL应用与实现】23: 如何使用std::mem_fn (since C++11)相关推荐

  1. 给定一组查找关键字(19,14,23,1,65,20,84,27,55,11,10,79) 哈希函数为:H(key)=key % 13, 哈希表长为m=15,设每个记录的查找概率相等。【MOOC】

    目   录 题 目①[关键字(19, 14, 23, 1, 65, 20, 84, 27, 55, 11, 10, 79)] 解法一(线性探测再散列) 解法二(链地址法) 题 目②[关键字(19, 1 ...

  2. C++回调机制的几种实现方式

     Callback Callback的本质是设置一个函数指针进去,然后在需要触发某个事件时调用该方法, 比如Windows的窗口消息处理函数就是这种类型. 比如下面的示例代码,我们在Downloa ...

  3. C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)

    C++ 标准库可以分为两部分: 标准函数库: 这个库是由通用的.独立的.不属于任何类的函数组成的.函数库继承自 C 语言. 面向对象类库: 这个库是类及其相关函数的集合. C++ 标准库包含了所有的 ...

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

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

  5. C++_标准模板库STL概念介绍5-其他库与总结

    C++还提供了其他一些类库,这些类库更加专用. 例如,头文件complex为复数提供了类模板complex,包含用于float.long和long double的具体化. 这个类提供了标准的复数运算以 ...

  6. STL 源码剖析 空间配置器

    以STL的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体地说是指容器,container) 的背后 但是STL的操作对象都存放在容器的内部,容器离不开内存空间的分配 为什么 ...

  7. STL 中的容器们(四)

    STL 中的容器们 for (int i = 0; i < coll.size()-1; ++i){... } 上述代码的写法,coll.size()-1 语句是会出问题的,STL 的所有容器的 ...

  8. [技术] OIer的C++标准库 : STL入门

    注: 本文主要摘取STL在OI中的常用技巧应用, 所以可能会重点说明容器部分和算法部分, 且不会讨论所有支持的函数/操作并主要讨论 C++11 前支持的特性. 如果需要详细完整的介绍请自行查阅标准文档 ...

  9. 275.算法设计工具―STL

    1.概述 1.1定义 STL主要由container(容器).algorithm(算法)和iterator(迭代器)三大部分构成,容器用于存放数据对象(元素),算法用于操作容器中的数据对象. 1.2s ...

最新文章

  1. 提取series中的数值_Mindfusion教程:WinForms中的实时图表
  2. Zeppelin:用于区块链应用的开源安全智能合约架构
  3. 皮一皮:中国好邻居!
  4. SharpDevelop 开源的 C# IDE ! 和 SharpZipLib
  5. Docker Review - dockerfile 实战_使用dockerfile制作tomcat镜像
  6. php验证中文姓名,我想在表单验证中加入中文姓名合法性模糊匹配判断?
  7. 【vue报错】——listen EADDRINUSE :::8080 解决方案
  8. draw graph
  9. notification源码分析_Ceilometer之notification agent代码分析
  10. Python 打印嵌套list中每个数据(遍历列表)
  11. Thunderspy: 7个硬件漏洞,影响9年来所有安装 Thunderbolt 的电脑
  12. iscc2021 easyweb
  13. lch 儿童围棋课堂 初级篇1 ( (李昌镐 著))
  14. Base64系列第一篇 Base64介绍
  15. 用Jmeter分布式测试——多台电脑做压力测试
  16. long型和int型的区别
  17. vue大文件下载(下载进度展示)
  18. Multiple users(Guest mode) 多用户或访客模式调试
  19. jquery 删除数组
  20. 【软件工程大作业】快递代拿小程序项目 (第十组)

热门文章

  1. 武汉大学 计算机学院 许传奇,许永超 - 教师简历 CV- 武汉大学计算机学院
  2. 2020最新的web前端体系和路线图,想学web前端又不知道从哪开始的快来瞧一瞧呀
  3. R语言垃圾邮件分类--朴素贝叶斯(机器学习)
  4. 2019年山东省第十届ACM程序设计竞赛 比赛总结
  5. 深入浅出matplotlib(96):标记的疏密控制
  6. 企业WiFi管理 保卫我们的信息安全
  7. 红米5a手机html查看器,红米5A如何截图 红米5A手机截图方法【详细介绍】
  8. 除夕最绚丽3D烟花代码(html+音效)
  9. 如何修改PC端微信消息提示音
  10. Android Zxing识别图片二维码识别率低