我们知道,普通函数指针是一个可调用对象,但是成员函数指针不是可调用对象。因此,如果我们想在一个保存string的vector中找到第一个空string,不能这样写:

vector<string> svec;

//...初始化

auto f = &string::empty; //fp是一个成员函数指针,指向string的empty函数

find_if(svec.begin(), svec.end(), fp); //错误 find_if算法需要一个可调用对象,但是fp是一个指向成员函数的指针

这里find_if算法查找第一个具有特定大小的元素,类似find算法,find_if算法接受一个迭代器,表示一个范围,第三个参数是一个是一个谓词,find_if算法对输入序列中的每个元素调用这个指定的谓词(可调用表达式,其返回结果是一个能用作条件的值),返回第一个使谓词返回非0值的元素,如果不存在这样的元素,返回尾后迭代器。简单的说,就是从输入序列中返回第一个满足谓词的值。

我们可以使用三种方式从指向成员函数的指针fp生成一个可调用对象:

1.使用function生成一个可调用对象

function<bool (const string&)> fcn = &string::empty;

find_if(svec.begin(),svec.end(),fcn)

2.使用mem_fn生成一个可调用对象

mem_fn()把可以从成员指针生成一个可调用对象,与function不同,mem_fn可以根据成员指针的类型推断可调用对象的类型,无序用户显式地指定:

find_if(svec.begin(), svec.end(), mem_fn(&string::empty));

使用mem_fn(&string::empty)生成一个可调用对象,该对象接受一个string实参,返回一个bool值。

mem_fn生成的可调用对象可以通过对象调用,也可以通过指针调用:

auto f = mem_fn(&string::empty); //f接受一个string或者string*
f(*svec.begin()); //传入一个string对象,f使用.*调用empty
f(&svec[]); //传入一个string对象,f使用->*调用empty

可以认为mem_fn生成的可调用对象含有一堆重载的函数调用运算符:一个接受string*,另一个接受string&。

3.使用bind生成一个可调用对象

auto it = find_if(svec.begin(), svec.end(), bind(&string::empty,_1));

与mem_fn类似,bind生成的可调用对象的第一个实参既可以是string的指针,也可以是string的引用:

auto f = bind(&string::empty,_1);
f(*svec.begin()); //正确:实参是一个string, f使用.*调用empty f(&svec[]);   //正确:实参是一个string的指针, f使用->*调用empty

下面的例子来自cplusplus上mem_fn的用法:

// mem_fn example
#include <iostream> // std::cout
#include <functional> // std::mem_fn struct int_holder {
int value;
int triple() {return value*;}
}; int main () {
int_holder five {}; // 直接调用成员函数
std::cout << five.triple() << '\n'; //15 // 使用mem_fn调用
auto triple = std::mem_fn (&int_holder::triple);
std::cout << triple(five) << '\n'; // return ;
}

参考:http://www.cplusplus.com/reference/functional/mem_fn/

     《C++ primer》

从成员函数指针生成可调用对象:function<>、mem_fn()和bind()的更多相关文章

  1. C/C++ 类成员函数指针 类成员数据指针

    普通函数指针:  "return_type (*ptr_name)(para_types) " 类成员函数指针: "return_type (class_name::*p ...

  2. 成员函数指针与高性能C++委托

    1 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做“闭包(closure)”或“委托(delegate)”)在一些语言中已经证明了它宝贵的价值. ...

  3. [转]成员函数指针与高性能的C++委托

    原文(作者:Don Clugston):Member Function Pointers and the Fastest Possible C++ Delegates 译文(作者:周翔): 成员函数指 ...

  4. 成员函数指针,动态绑定(vc平台)

    上一篇介绍了gcc对成员函数指针做了thunk的处理,本篇介绍vc对成员函数指针如何处理,还有动态绑定相关的处理. 同样用回上一篇的例子: struct point {float x,y;}; str ...

  5. 自制反汇编工具使用实例 其二(使用xmm寄存器初始化对象,以及空的成员函数指针)

    在反汇编代码中,当看到xmm寄存器,第一反应是将要进行浮点操作或访问,但是更加多的情况是在使用xmm寄存器初始化局部对象. 下面是自制反汇编工具翻译出来的代码: // -[CALayer setAll ...

  6. 获得函数返回值类型、参数tuple、成员函数指针中的对象类型

    //function_traits.h,获得函数返回值类型.参数tuple.成员函数指针中的对象类型 //参考https://github.com/qicosmos/cosmos/blob/maste ...

  7. C++的类成员和类成员函数指针

    类成员函数指针: 用于访问类成员函数,和一般函数指针有区别. 类成员函数处理的是类数据成员,声明类成员函数指针的同时,还要指出具体是哪个类的函数指针才可以.调用时也要通过对象调用. 而对于类的静态成员 ...

  8. Item 17: 理解特殊成员函数的生成规则

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 C++的官方说法中,特殊成员函数是C++愿意去主动生成的.C++9 ...

  9. 成员函数指针与高效C++委托 (delegate)

    下载实例源代码 - 18.5 Kb 下载开发包库文件 - 18.6 Kb 概要 很遗憾, C++ 标准中没能提供面向对象的函数指针. 面向对象的函数指针也被称为闭包(closures) 或委托(del ...

随机推荐

  1. 《hello-world团队》第七次作业:团队项目设计完善&编码

    项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十一 团队作业7:团队项目设计完善&编码 团队名称 <hello--w ...

  2. unity里blit的load store action设置

    做blit的 load store action时 用 setrendertarget做 之后blit 参数用 BuiltinRenderTextureType.CurrentActive https ...

  3. python 杂记-unittest

    介绍单元测试的好文:https://mp.weixin.qq.com/s/njxc8GXSlc3z_RibK70ROg setUpModule/tearDownModule:在整个模块的开始和结束时被 ...

  4. HDU 2454 Degree Sequence of Graph G——可简单图化&&Heavel定理

    题意 给你一个度序列,问能否构成一个简单图. 分析 对于可图化,只要满足度数之和是偶数,即满足握手定理. 对于可简单图化,就是Heavel定理了. Heavel定理:把度序列排成不增序,即 $deg[ ...

  5. 使用jQuery快速高效制作网页交互特效--JavaScript操作BOM对象

    JavaScript操作BOM 一.window对象: 二.window对象的属性和方法 1.windows对象的常用属性: 语法:window.属性名="属性值" 2.windo ...

  6. Color Highlight 鼠标放在 #f3f 上面其背景会变成相应的颜色的插件 DocBlockr自动补全注释

    不是  Color Highlighter    而是 Color Highlight  少了 er  颜色功能还是很爽的,找了好久 鼠标放在 #f3f 上面其背景会变成相应的颜色的插件 DocBlo ...

  7. asp.net文件上传下载组件

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  8. 2-set奶牛议会

    Description 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 & ...

  9. Sprite Atlas与Sprite Mask详解

    https://www.sohu.com/a/169409304_280780 Unity 2017.1正式发布后,带来了一批能帮助大家更加简化工作流的新功能.今天这篇文章,将由Unity技术经理成亮 ...

  10. Java把多个list 合并成一个并去重

           开发过程中遇到一个合并去重问题,任务完成后,总结出来一个比较简单的方法.对于List中不同类型的数据,需要采用不同的处理方式.List中如果是基础数据类型,直接合并去重即可:如果是对象类 ...