c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值。

可调用对象

c++中的可调用对象存在以下几类: 
(1)函数指针 
(2)具有operator()成员函数的类对象(仿函数) 
(3)可被转换为函数指针的类对象 
(4)类成员(函数)指针

  1. void func(void){
  2. //....
  3. }
  4.  
  5. struct Foo{
  6. void operator()(void){
  7. //...
  8. }
  9. };
  10.  
  11. struct Bar{
  12. using fr_t = void(*)(void);
  13. static void func(void){
  14. //...
  15. }
  16. operator fr_t(void){ //可以进行隐式转换,转换结果为 fr_t 为一个函数指针
  17. return func; //operator xxx (void) 函数可以对类的对象进行隐式转换
  18. }
  19. };
  20.  
  21. struct A{
  22. int a_;
  23. void mem_func(void){
  24. //...
  25. }
  26. };
  27. int main(){
  28. void(* func_ptr)(void) = &func; //1.函数指针
  29. func_ptr();
  30.  
  31. Foo foo; //2. 仿函数
  32. foo();
  33.  
  34. Bar bar;
  35. bar(); //可被转化为函数指针的类对象
  36.  
  37. void (A::*mem_func_ptr)(void) = &A::mem_func; //类成员函数指针
  38.  
  39. int A::*mem_obj_ptr = &A::a; //类成员指针
  40. return 0;
  41. }

可调用对象包装器——std::function

c++11通过std::function, std::bind统一了可调用对象的各种操作。std::function是可调用对象的包装器,它是一个类模板,可以容纳类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延时执行它们。 
std::function<返回值(参数类型)> f;

  1. void func(void){
  2. }
  3. class Foo{
  4. public:
  5. static int foo_func(int a){
  6. std::cout << "hello" <<std::endl;
  7. return a;
  8. }
  9. };
  10. int main(){
  11. std::function<void(void)> f;
  12. f = func;
  13. std::function<int(int)> = Foo::foo_func;
  14. return 0;
  15. }

std::bind绑定器

std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用 std::function进行保存,并延迟调用到任何我们需要的时候。它主要有两大作用: 
(1)将可调用对象与其参数一起绑定成一个仿函数 
(2)将多元(参数个数为n>1)可调用对象转成x元( 0 <= 0 <= n)元可调用对象,即只绑定部分参数。 
(3)使用bind可以将类的非静态成员函数绑定起来,赋值给一个可执行std::function对象

  1. #include<functional>
  2. using namespace std;
  3.  
  4. int func(int a, int b){
  5. std::cout << "a = " << a << ", b = " << b << std::endl;
  6. return a + b;
  7. }
  8.  
  9. class A{
  10. public:
  11. int mem_func(int a, int b){
  12. std::cout << "a = " << a << ", b = " << b << std::endl;
  13. return a + b;
  14. }
  15. };
  16. int main(){
  17. //直接生成一个可调用对象,然后调用,参数为3
  18. //bind(func, 1, std::placeholders::_1)中表示将参数1 和参数 std::placeholders::_1作为函数func的参数,绑定成另一个可执行对象。
  19. //在绑定的时候, 按照顺序,1 作为 func(int a, int b) 中形参a的实参; std::placeholders::_1 作为 func(int a, int b) 中形参b的实参
  20.  
  21. //std::placeholders::_1 是占位符,表示将绑定后得到的可执行对象进行调用的时候,实参的第1个,放到 std::placeholders::_1的位置上去
  22. //依次,std::placeholders::_2 将调用的时候实参的第2个,放到该位置上去
  23. //注意,占位符 std::placeholders::_x 中x必须小于等于调用的时候实际参数的个数!!
  24. std::bind(func, 1, std::placeholders::_1)(3); //输出 a = 1, b = 3
  25. std::bind(func, 1, std::placeholders::_2)(3, 6); //输出 a = 1, b = 6
  26.  
  27. //用function可调用对象f保存bind后的结果
  28. std::function<int(int)> f = std::bind(func, 1, std::placeholders::_1);
  29. f(2); //输出 a = 1, b = 2
  30. f = std::bind(func, std::placeholders::_1, 1);
  31. f(3); //输出 a = 3, b = 1
  32.  
  33. //将类的非静态成员函数,以及类的对象实例,进行绑定
  34. A a;
  35. f = std::bind(&A::mem_func, a, 1, std::placeholders::_1);
  36. f(10);
  37. return 0;
  38. }
使用组合bind函数

bind可以组合多个函数,假设要找出集合中大于5小于10的元素个数. 
判断一个数是否大于5的闭包,代码std::bind(std::greater< int>(), std::placeholders::_1, 5) 
判断一个数是否小于10的闭包,代码std::bind(std::less_equal< int>(), std::placeholders::_1, 10) 
然后进行组合,得到:

  1. using std::placeholders::_1;
  2. //查找集合中大于5小于等于10的元素个数
  3. auto f = std::bind(
  4. std::logic_and<bool>(),
  5. std::bind(std::greater<int>(), _1, 5),
  6. std::bind(std::less_equal<int>(), _1, 10));
  7.  
  8. int count = std::count_if(coll.begin(), coll.end(), f);

c++11——std::function和bind绑定器的更多相关文章

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

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

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

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

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

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

  4. C++11 std::function、std::bind和lambda表达式

    参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html 一.关于std::function与std::bin ...

  5. C/C++ C++ 11 std::function和std::bind用法

    std::bind() std::bind 主要用于绑定生成目标函数,一般用于生成的回调函数,cocos的回退函数都是通过std::bind和std::function实现的.两个点要明白: 1.绑定 ...

  6. 利用C++11的function和bind简化类创建线程

    问题引出 当在类中需要创建线程时,总是因为线程函数需要定义成静态成员函数,但是又需要访问非静态数据成员这种需求,来做若干重复性的繁琐工作.比如我以前就经常定义一个静态成员函数,然后定一个结构体,结构体 ...

  7. C++11 中function和bind以及lambda 表达式的用法

    关于std::function 的用法:  其实就可以理解成函数指针 1. 保存自由函数 void printA(int a) { cout<<a<<endl; } std:: ...

  8. C++中的仿函数,std::function和bind()的用法

    1.仿函数:又叫std::function,是C++中的一个模板类 2.C语言中的函数指针: int  add(int a,int b) { return a+b; } typedef int (*f ...

  9. C++11 std::function用法

    转自 http://www.hankcs.com/program/cpp/c11-std-function-usage.html function可以将普通函数,lambda表达式和函数对象类统一起来 ...

随机推荐

  1. Error reading field 'throttle_time_ms': java.nio.BufferUnderflowException

    可能出现的问题: ERROR o.a.k.c.p.i.Sender – Uncaught error in kafka producer I/O thread: org.apache.kafka.co ...

  2. Unity3D中的序列化测试

    Unity3D中序列化字段常使用[SerializeField],序列化类常采用[System.Serializable],非序列化采用[System.NonSerialized]. 序列化类使用时发 ...

  3. 【C#】Config配置文件的读写,及无法写入/保存配置文件的问题

    目的: 一些数据为了在项目打包好后也能方便的修改和调用,通常会把这些数据放到配置文件中,避免硬编码,修改配置文件内容更方便,而不用修改源代码. 使用: 在解决方案资源管理器中找到App.config文 ...

  4. http://blog.csdn.net/beitiandijun/article/details/41678251

    http://blog.csdn.net/beitiandijun/article/details/41678251

  5. [Django学习]视图

    视图 视图接受Web请求并且返回Web响应 视图就是一个python函数,被定义在views.py中 响应可以是一张网页的HTML内容,一个重定向,一个404错误等等 响应处理过程如下图: 1. UR ...

  6. 04 memory structure

    本章提要--------------------------------------------------SGA: System Global Area ( 包括background process ...

  7. TCP/IP和Socket的关系

    要写网络程序就必须用Socket,这是程序员都知道的.而且,面试的时候,我们也会问对方会不会Socket编程?一般来说,很多人都会说,Socket编程基本就是listen,accept以及send,w ...

  8. socket和http

    套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议 ...

  9. 关于Cocos2d-x很多奇怪的报错

    1.说什么找不到类和命名空间,但是已经包含头文件 项目-属性-配置属性-C/C++-附加包含目录-编辑-添加新行-写上$(EngineRoot) 2.很多语句报错,但是都没问题 我是这样理解的,书上的 ...

  10. am335x LCD参数更改

    /******************************************************************** * am335x LCD参数更改 * * 本文记录am335 ...