这次要讲的是:c++11中的bind和function

std::function

它是函数、函数对象、函数指针、和成员函数的包装器,可以容纳任何类型的函数对象,函数指针,引用函数,成员函数的指针。
以统一的方式处理函数、函数对象、函数指针、和成员函数。
允许保存和延迟执行函数。

  • 函数和成员函数作为function
void G();
struct A
{
void H(){}
}; std::function<void()> f = G; //全局函数 A a;
std::function<void()> f = 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%==)
f(x);
} void G(int x)
{
cout<<x<<endl;
} void H(int x)
{
cout<<x+<<endl;
} void TestFoo()
{
auto f = std::bind(G, std::placeholders::_1);
Foo(, f); //在Foo函数外面更改f的行为
f = std::bind(H, std::placeholders::_1);
Foo(, 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();
  • bind简化和增强bind1st和bind2nd

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

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

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

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

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

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

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

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

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

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

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

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

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

c++11 boost技术交流群:296561497,欢迎大家来交流技术。

(原创)C++11改进我们的程序之简化我们的程序(五)的更多相关文章

  1. (原创)C++11改进我们的程序之简化我们的程序(八)

    本次要讲的是如何通过泛型函数来简化我们的程序. 泛型函数除了之前介绍的一些优点外还有两个重要的优点 1.消除重复逻辑,提高程序的内聚性和健壮性 泛型函数在某种程度上用来弥补泛型类型的不足.通过泛型类型 ...

  2. (原创)C++11改进我们的程序之简化我们的程序(二)

    这次要讲的是:C++11如何通过组合函数来简化我们的程序.关于组合函数,大家可能对这个概念有点陌生.组合函数是将N个一元函数组成一种更复杂的函数,每个函数的返回值作为参数传给下一个函数,直到传到最后一 ...

  3. C++11改进我们的程序之简化我们的程序1

    C++11改进我们的程序之简化我们的程序(一) C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返 ...

  4. (原创)C++11改进我们的程序之简化我们的程序(四)

    这次要讲的是:c++11统一初始化.统一begin()/end()和for-loop循环如何简化我们的程序 初始化列表 c++11之前有各种各样的初始化语法,有时候初始化的时候还挺麻烦,比较典型的如v ...

  5. (原创)C++11改进我们的程序之简化我们的程序(三)

    这次要讲的是:C++11如何通过auto.decltype和返回值后置来简化我们的程序. auto和c#中的var类似,都是在初始化时自动推断出数据类型.当某个变量的返回值难于书写时,或者不太确定返回 ...

  6. (原创)C++11改进我们的程序之简化我们的程序(一)

    C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返回值类型来简化我们的程序.在谈到简化之前,我们先 ...

  7. (原创)c++11改进我们的模式之改进代理模式,实现通用的AOP框架

    c++11 boost技术交流群:296561497,欢迎大家来交流技术. 本次要讲的时候如何改进代理模式,具体来说是动态代理模式,动态代理模式一般实现AOP框架,不懂AOP的童鞋看这里.我前面的博文 ...

  8. (原创)c++11改进我们的模式之改进命令模式

    模式虽然精妙,却难完美,比如观察者模式中观察者生命周期的问题:比如访问者模式中循环依赖的问题等等:其它很多模式也存在这样那样的一些不足之处,如使用场景受限.实现复杂.不够简洁.不够通用等.但我觉得不足 ...

  9. (原创)c++11改进我们的模式之改进访问者模式

    本次讲c++11改进我们的模式之改进访问者模式 访问者模式是GOF23个设计模式中比较复杂的模式之一,但是它的功能也很强大,非常适合稳定的继承层次中对象的访问,可以在不修改被访问对象的情况下,动态添加 ...

  10. (原创)C++11改进我们的程序之简化我们的程序(七)

    这次要讲的内容是:c++11中的tuple(元组).tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多 ...

随机推荐

  1. 基于Echarts的中国地图数据展示

    发布时间:2018-10-31   技术:javascript+html5+canvas   概述 基于echarts的大数据中国地图展示,结合API定制,开发样式,监听鼠标事件,实现带参数路由跳转等 ...

  2. iOS手势的综合运用

    //自定义一个VIEW封装手势功能 // CustormView.m // gesterDemoo // // Created by ganchaobo on 13-7-13. // Copyrigh ...

  3. (原)PyTorch中使用指定的GPU

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6836568.html PyTorch默认使用从0开始的GPU,如果GPU0正在运行程序,需要指定其他G ...

  4. Linux删除文件出现rm: cannot remove `.user.ini': Operation not permitted

    转自:https://blog.csdn.net/sinat_35861727/article/details/79040755 在Linux中rm -rf的威力是十分巨大的,特别是附带了 -f 参数 ...

  5. webservice(草稿)

    1.  概述 WebService是一种跨编程语言和跨操作系统平台的远程调用技术. Webservice是被定义用来使不同应用之间通过网络传输数据的一种标准,此标准和具体的语言无关,至于哪种语言提供接 ...

  6. 单个APP页面支持屏幕旋转

    1.info中支持所有的方向 2.APPDelega.h中添加属性 @property (nonatomic,assign) BOOL allowRotate; APPdelegate.m中实现方法 ...

  7. SIGTERM等信号含义【转】

    主要是做sigterm 和sigkill区别的比较,之前的好多操作,在结束正在运行的一个程序的时候,常用kill,这个以后的注意,在sigterm不起作用的时候,再使用kill; 原文地址:http: ...

  8. 路由器下CLI界面

    CLI(command-line interface,命令行界面)是指可在用户提示符下键入可执行指令的界面. CLI是Command Line Interface的缩写,即命令行界面.CLI界面是所有 ...

  9. 聊聊阻塞与非阻塞、同步与异步、I/O模型

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端:  同步: 所谓同步,就是在c端 ...

  10. windbg-.foreach循环输入(windbg script)

    .foreach .foreach 关键字分析一个或多个命令的输出并将该输出中每一个值作为另一个或多个命令的输入 .foreach [Options] ( Variable  { InCommands ...