std::function

它是函数、函数对象、函数指针、和成员函数的包装器,可以容纳任何类型的函数对象,函数指针,引用函数,成员函数的指针。

以统一的方式处理函数、函数对象、函数指针、和成员函数。

允许保存和延迟执行函数。

函数和成员函数作为function

void G();
struct A
{
void H(){}
}; std::function<void()> f = G; //全局函数 A a;
std::function<void()> f 1= std::bind(&A::H, a); //成员函数

可以用function取代函数指针。因为它可以保存函数延迟执行,所以比较适合作为回调函数,也可以把它看做类似于c#中特殊的委托,只有一个成员的委托。

struct A
{
A(std::function<void()>& f):m_callback(f)
void Notify()
{
m_callback();//回调到上层
} std::function<void()> m_callback;
}

function还可以作为函数入参,这样可以在函数外部控制函数的内部行为了,让我们的函数变得更加灵活。

void Foo(int x, std::function<void(int)>& f)
{
if(x%2==0)
f(x);
} void G(int x)
{
cout<<x<<endl;
} void H(int x)
{
cout<<x+2<<endl;
} void TestFoo()
{
auto f = std::bind(G, std::placeholders::_1);
Foo(4, f); //在Foo函数外面更改f的行为
f = std::bind(H, std::placeholders::_1);
Foo(4, f);
}

std::bind绑定器

将函数、成员函数和闭包转成function函数对象

将多元(n>1)函数转成一元函数或者(n-1)元函数。

void H(int a);
//绑定全局函数
auto f11 = std::bind(H, std::placeholders::_1);
auto的类型实际上是std::function<void(int)> //绑定带参数的成员函数
std::function<void (char*, int)> f = std::bind(&ReadHandler::ConnectPreProcess, this, std::placeholders::_1, std::placeholders::_1); //三元函数转换成一元函数
int f(int, char, double);
// 绑定f()函数调用的第二个和第三个参数,
// 返回一个新的函数对象为ff,它只带有一个int类型的参数
auto ff = bind(f, _1, ‘c’, 1.2);
int x = ff(7);

bind简化和增强bind1st和bind2nd

  其实bind简化和增强了之前标准库中bind1st和bind2nd,它完全可以替代bind1s和bind2st,并且能组合函数。我们知道bind1st和bind2nd将一个二元算子转换成一个一元算子。

  

//查找元素值大于10的元素的个数
int count = count_if(coll.begin(), coll.end(), std::bind1st(less<int>(), 10));
//查找元素之小于10的元素
int count = count_if(coll.begin(), coll.end(), std::bind2nd(less<int>(), 10));

 本质上是对一个二元函数less的调用,但是它却要分别用bind1st和bind2nd,而且还要想想到底是用bind1st还是bind2nd,用起来感觉不方便。现在用bind,就可以以统一的方式去实现了。

 

//查找元素值大于10的元素的个数
int count = count_if(coll.begin(), coll.end(), bind(less<int>(), 10, _1));
//查找元素之小于10的元素
int count = count_if(coll.begin(), coll.end(), bind(less<int>(), _1, 10));
这样我就不用关心到底是用bind1st还是bind2nd了,只要用bind就都搞定了。

bind函数组合

bind的还有一个强大之处就是函数组合。假设我们要找出集合中大于5小于10的元素个数怎么做呢?我们需要一个逻辑与才能做到类似于:

std::bind(std::logical_and<bool>(),_1,_2);

然后,我们需要另一个谓词来回答 _1 是否大于5。

std::bind(std::greater<int>(),_1,5);

然后,我们还需要另一个谓词来回答 _1 是否小于等于10。

std::bind(std::less_equal<int>(),_1,10);

最后,我们需要把它们两个用逻辑与合起来,就象这样:

//查找集合中大于5小于10的元素个数
auto f = bind(std::logical_and<bool>(), bind(std::greater<int>(),_1,5), bind(std::less_equal<int>(),_1,10));
int count = count_if(coll.begin(), coll.end(), f);

c++11中推出function是为了泛化函数对象,函数指针,引用函数,成员函数的指针,让我们可以按更统一的方式写出更加泛化的代码;推出bind是为了替换和增强之前标准库的bind1st和bind2st,让我们的用起来更方便!

(1)bind预先绑定的参数需要传具体的变量或值进去,对于预先绑定的参数,是pass-by-value的

(2)对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的

(3)bind的返回值是可调用实体,可以直接赋给std::function对象

(4)对于绑定的指针、引用类型的参数,使用者需要保证在可调用实体调用之前,这些参数是可用的

(5)类的this可以通过对象或者指针来绑定

引用:http://www.cnblogs.com/qicosmos/p/3302144.html

[C++]C++11:Function与Bind的更多相关文章

  1. c++11——std::function和bind绑定器

    c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值. 可调用对象 c++中的可调用对象存在以下几类: (1)函数指针 (2)具有ope ...

  2. C++11 学习笔记 std::function和bind绑定器

    C++11 学习笔记 std::function和bind绑定器 一.std::function C++中的可调用对象虽然具有比较统一操作形式(除了类成员指针之外,都是后面加括号进行调用),但定义方法 ...

  3. C++11绑定器bind及function机制

    前言 之前在学muduo网络库时,看到陈硕以基于对象编程的方式,大量使用boost库中的bind和function机制,如今,这些概念都已引入至C++11,包含在头文件<functional&g ...

  4. C++11新特性之九——function、bind以及lamda表达式总结

    本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lambda表达式, function对象和bind机制.之所以把这三块放在一起讲,是因为这三块之间有着非常密切的关系,通过对比学习,加深对 ...

  5. 【转载】C++ function、bind和lambda表达式

    本篇随笔为转载,原贴地址:C++ function.bind和lambda表达式. 本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lambda表达式, function对象和bind机制 ...

  6. 理解 JavaScript 中的 Function.prototype.bind

    函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其 ...

  7. 深入理解javascript中的Function.prototye.bind

    函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其 ...

  8. C++类重载函数的function和bind使用

    在没有C++11的std::function和std::bind之前,我们使用函数指针的方式是五花八门,结构很繁琐难懂.C++11中提供了std::function和std::bind统一了可调用对象 ...

  9. 一起Polyfill系列:Function.prototype.bind的四个阶段

    昨天边参考es5-shim边自己实现Function.prototype.bind,发现有不少以前忽视了的地方,这里就作为一个小总结吧. 一.Function.prototype.bind的作用 其实 ...

  10. 聊聊Function的bind()

    bind顾名思义,绑定. bind()方法会创建一个新函数,当这个新函数被调用时,它的this值是传递给bind()的第一个参数,它的参数是bind()的其他参数和其原本的参数. 上面这个定义最后一句 ...

随机推荐

  1. 5 why 分析法,一种用于归纳抽象出解决方案的好方法

    最近在看了<微信背后的产品观 - 张小龙手抄版>,其中有段话如下: 用户需求是零散的,解决方案是归纳抽象的过程 那如何归纳抽象呢?是否有一定的实践方法论呢?经过一轮探讨和学习,有这些答案: ...

  2. linux读写一个NTFS分区

    为了读写一个NTFS分区的数据,挂载的时候出现错误提示如下: root@tv:/home/xx# mount -t ntfs-3g /dev/sdb1 /media/sxx/硬盘B-临时文件 The ...

  3. echarts标题(title)配置

    var option = {         //标题         title : {             show:true,//显示策略,默认值true,可选为:true(显示) | fa ...

  4. 👍SpringSecurity单体项目最佳实践

    SpringSecurity单体项目最佳实践 到这里,我们的SpringSecurity就已经完结啦,文章中可能有些地方不能做到全面覆盖,视频教程地址 初始项目地址 完成项目地址 1.搭建环境 建议下 ...

  5. 【题解】CF45I TCMCF+++

    题面传送门 题目描述 有 \(n\) 个数 \(a_i\) 请你从中至少选出一个数,使它们的乘积最大 解决思路 对于正数,对答案一定有贡献(正数越乘越大),所以输入正数时直接输出即可. 对于负数,如果 ...

  6. 嵌入式-C语言基础:联合体和共用体的概念

    有时候同一块内存空间存放类型不同,不同类型的变量共享一块空间. 结构体和共用体的区别: (1)结构体元素有各自单独空间,共用体元素共享空间,空间大小由最大类型确定. (2)结构体元素互不影响共用体赋值 ...

  7. MYSQL5.7 保姆级安装教程

    现在要是说mysql是什么东西,就不礼貌了 虽然有的同学没有进行系统的深入学习,但应该也有个基本概念 [不了解也没关系,后续会进行mysql专栏讲解]简单来说,存储数据的 学习mysql,就要先安装它 ...

  8. i春秋xss平台

    点开是个普普通通的登录窗口,没有注册,只有登录,抓住包也没获取什么有用的信息,看了看dalao的wp才知道怎么做,首先抓包然后修改参数的定义来让其报错,pass原本的应该为整数,pass[]=就可以让 ...

  9. C++快速幂

    C++快速幂 快速幂的作用: 当我们做一些高次幂的计算时,就不能直接进行暴力的计算.例如:需要计算2^n 并且n≤10^18.这时候如果我们直接进行暴力的计算,时间复杂度为O ( n ),那么肯定会超 ...

  10. MySQL57 zip安装

    引用:MySQL5.7的.zip文件的配置安装   由于MySQL5.7之后在javaEE中交互的端口发生了变化,而MySQL官网中5.6.5.7版本64位的只有.zip文件,而.zip文件不像直接下 ...