std::bind 用于绑定一个函数,返回另外一种调用方式的函数对象 ,可以改变参数顺序 和个数,特别是在多线程的程序中,经常用它将函数进行包装,然后打包发送给工作线程,让工作线程去执行我们的任务。

  std::function 用于构建一个函数特别是 回调函数  ,用于替代 函数指针/*常和匿名函数一起用回调*/

参考以下代码:

#include<iostream>

#include "functional"

using namespace std;

double calculate(double x, double y, char op)
{
switch (op)
{ case '+':
{
return x + y;
}break; case '-':
{
return x - y;
}break;
}
return ;
} int main()
{ //bind
auto plus = std::bind(calculate, std::placeholders::_1, std::placeholders::_2, '+');/*calculate 参数1 参数2*/
auto sub = std::bind(calculate, std::placeholders::_2, std::placeholders::_1, '-');/*calculate 参数2 参数1*/
cout << plus(, ) << endl;
cout << sub(, ) << endl;/*调用时候 5为 calculate的第二个参数*/ //function
typedef std::function<double(double , double , char)> func;
func fun = calculate;
cout << fun(, , '+') << endl;; //function ptr
double (*p)(double, double, char) =calculate;
cout << p(, , '+') << endl;; //function + bind
std::function<double (double , double )> plus_2;
plus_2 = plus;
cout << plus_2(, ) << endl;; system("pause");
return ; }

  bind是这样一种机制,它可以预先把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调 用实体,这种机制在回调函数的使用过程中也颇为有用。其实最早在C++98的时候,就已经有了std::bind1st和std::bind2nd分别用来绑定functor的两个参数,具体代码就不演示了,查查资料就知道了。这个特性在当时并没有引起太多的重视,可以说是食之无味。
  C++11中提供了std::bind,可以说是一种飞跃的提升,bind本身是一种延迟计算的思想,它本身可以绑定普通函数、全局函数、静态函数、类静态函数甚至是类成员函数。

#include <iostream>
#include <functional>
using namespace std; int TestFunc(int a, char c, float f)
{
cout << a << endl;
cout << c << endl;
cout << f << endl; return a;
} int main()
{
auto bindFunc1 = bind(TestFunc, std::placeholders::_1, 'A', 100.1);
bindFunc1(); cout << "=================================\n"; auto bindFunc2 = bind(TestFunc, std::placeholders::_2, std::placeholders::_1, 100.1);
bindFunc2('B', ); cout << "=================================\n"; auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
bindFunc3(100.1, , 'C'); return ;
}

  从上面的代码可以看到,bind能够在绑定时候就同时绑定一部分参数,未提供的参数则使用占位符表示,然后在运行时传入实际的参数值。

  PS:绑定的参数将会以值传递的方式传递给具体函数,占位符将会以引用传递。

  众所周知,静态成员函数其实可以看做是全局函数,而非静态成员函数则需要传递this指针作为第一个参数,所以std::bind能很容易地绑定成员函数。

  bind最终将会生成一个可调用对象,这个对象可以直接赋值给std::function对象,而std::bind绑定的可调用对象可以是Lambda表达式或者类成员函数等可调用对象。它能随意绑定任何函数,将所有的函数都能统一到std::function。

std::bind和std::function的更多相关文章

  1. c++11特性与cocos2d-x 3.0之std::bind与std::function

    昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0 ...

  2. 第12课 std::bind和std::function(3)_std::function可调用对象包装器

    1. std::function (1)首先是一个类模板,用于包装可调用对象.可以容纳除了类成员(函数)指针之外的所有可调用对象. (2)可以将普通函数,lambda表达式和函数对象类统一起来.尽管它 ...

  3. 第11课 std::bind和std::function(2)_std::bind绑定器

    1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...

  4. std::bind与std::ref, why and how

    首先解释下为什么有时候需要bind. 我们可以用bind从函数T add(T a, T b)造出个inc()来,即把b写死为1.这个例子本身比较傻,但有不傻的应用. template<typen ...

  5. 第10课 std::bind和std::function(1)_可调用对象

    1. 几种可调用对象(Callable Objects) (1)普通函数指针或类成员的函数指针 (2)具有operator()成员函数的类对象(仿函数).如c++11中的std::function类模 ...

  6. C++11 std::bind std::function 高级使用方法

    从最基础的了解,std::bind和std::function /* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ # ...

  7. C++ 中std::function 、std::bind的使用和lambda的使用

    std::function是可调用对象的包装器:std::bind是将可点用对象和其参数一起进行绑定,且绑定后的结果可以使用std::function对象进行保存,并延迟调用到需要调用的时候: 在C+ ...

  8. C++ 11 std::function std::bind使用

    cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码: auto closeItem = MenuItemImage::create( "CloseNorm ...

  9. C++11新特性之二——std::bind std::function 高级用法

    /* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ #include <iostream> #includ ...

随机推荐

  1. tesseract-ocr 出现 错误 Please make sure the TESSDATA_PREFIX environment variable is set to the parent d irectory of your "tessdata" directory.解决方案

    简单就是说把tessdata拷贝到exe的所在目录,或者设置TESSDATA_PREFIX环境变量

  2. mysql innobackupex xtrabackup 大数据量 备份 还原

    大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推荐xtrabackup,这个工具比mysqldump要快很多. 一.Xtrabackup介绍 1, ...

  3. HTTP学习笔记(1)ULR语法

    1,概述 当你打开一个浏览器则会进入一个主页,也许你会想只是打开了浏览器罢了,但是浏览器默默的把这个主页默认的网址发送出去,你只是不知道而已,你只是没有输入而已.我们来做个实验. 1,双击打开 2,可 ...

  4. 马踏飞燕——奔跑在Docker上的Spark

    目录 为什么要在Docker上搭建Spark集群 网络拓扑 Docker安装及配置 ssh安装及配置 基础环境安装 Zookeeper安装及配置 Hadoop安装及配置 Spark安装及配置 集群部署 ...

  5. C语言extern作用(全局变量)

    用C语言编写程序的时候,我们经常会遇到这样一种情况:希望在头文件中定义一个全局变量,然后包含到两个不同的c文件中,希望这个全局变量能在两个文件中共用. 举例说明:项目文件夹project下有main. ...

  6. keil 的头文件 .

    许多初学者使用网上下载的程序时都会遇到这样一个问题,就是头文件找不到.我想就这个问题说明一下./·首先,我们用到的KEIL有几种版本的,头文件也不同.有reg51.h和at89x51.h两种比较常见. ...

  7. 4.2.1 网络请求之HTTP

    HTTP请求&响应:(常用的只有Post与Get,还有Head/put/delete/connect/options/trace) Get&Post(建议用post规范参数传递方式,并 ...

  8. Java写的爬虫的基本程序

    这是一个web搜索的基本程序,从命令行输入搜索条件(起始的URL.处理url的最大数.要搜索的字符串),它就会逐个对Internet上的URL进行实时搜索,查找并输出匹配搜索条件的页面. 这个程序的原 ...

  9. 用c#开发微信 (9) 微渠道 - 推广渠道管理系统 4 部署测试 (最终效果图)

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本文是微渠 ...

  10. phoneGap2.9+eclipse开发环境和helloword案例

    不同机器安装和使用各不相同,这里也只是记录一下自己机器上面的使用过程. android安装环境前面的文章有些,这里不再说,直接上phoneGap的过程.因为phoneGap2.9.1需要安装nodej ...