验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

C++11 std::function和std::bind如何使用

阅读:1040 来源:乙速云 作者:代码code

C++11 std::function和std::bind如何使用

      概述

      C++11中的std::functionstd::bind是函数对象的重要组成部分,它们可以用于将函数和参数绑定在一起,形成一个可调用的对象。
      std::function可以存储任意可调用对象,包括函数指针、函数对象、lambda表达式等,而std::bind则可以将函数和参数绑定在一起,形成一个新的可调用对象。它们的使用可以大大简化代码,提高代码的可读性和可维护性。

      可调用对象

      C++中有如下几种可调用对象,函数、函数指针、lambda表达式、bind对象、函数对象
      其中,lambda表达式和bind对象是C++11标准中提出的(bind机制并不是新标准中首次提出,而是对旧版本中bind1st和bind2st的合并)。

      std::function

      std::function是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。
      使用std::function可以实现回调函数、事件处理等功能。

      std::function函数原型

      #include 
      template
      class function;
      //其中,R 表示返回值类型,Args... 表示参数类型列表。
      //例如,function 表示一个返回值为 int,接受一个 float 和一个 double 类型参数的函数对象。

      std::function的主要作用

      • 对C++中各种可调用实体(普通函数、Lambda表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的std::function对象,简化调用;

      • 对C++中现有的可调用实体的一种类型安全的包裹(如:函数指针这类可调用实体,是类型不安全的)。

      • 将函数作为参数传递给其他函数;

      • 将函数作为返回值返回;

      • 将函数对象作为参数传递给其他函数;

      • 将函数对象作为返回值返回。

      //例如,定义一个返回值为int,参数为两个int的函数对象: 
      std::functionfunc; 
      
      //可以将一个函数指针或lambda表达式赋值给函数对象: 
      int add(int a, int b) { return a +b; } 
      func = add; // 函数指针赋值 
      func = [](int a, int b) { return a + b; };// lambda表达式赋值 
      
      //调用函数对象可以使用operator(),例如:
      int result = func(1, 2); // 调用add函数,返回3

      std::function的优缺点

      • 优点:

      可以方便地实现回调函数、事件处理等功能,同时也可以用于实现函数对象的封装和传递。

      • 缺点:

      它的使用会带来一定的性能开销,因为它需要在运行时进行类型检查和动态分配内存。
      此外,如果使用不当,也容易引起内存泄漏和对象生命周期管理的问题。

      std::bind

      std::function是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。

      std::bind函数原型

      template 
      /unspecified/ bind(F&& f, Args&&... args);
      //其中,F是要绑定的函数对象,Args是要绑定的参数。返回值是一个新的可调用对象,可以直接调用或者存储起来后再调用。

      std::bind的主要作用

      • 将可调用对象和其参数绑定成一个仿函数;

      • 只绑定部分参数,减少可调用对象传入的参数。

      • 绑定函数对象的参数,生成一个新的可调用对象,可以方便地将函数对象作为参数传递给其它函数。

      • 可以将成员函数绑定到对象上,生成一个新的可调用对象,方便地调用成员函数。

      • 可以将成员函数绑定到对象指针上,生成一个新的可调用对象,方便地调用成员函数。

      • 可以将成员函数绑定到对象引用上,生成一个新的可调用对象,方便地调用成员函数。

      • 可以将函数对象绑定到函数指针上,生成一个新的可调用对象,方便地调用函数对象。

      • 可以将函数对象绑定到函数引用上,生成一个新的可调用对象,方便地调用函数对象。

      • 可以将函数对象绑定到std::function对象上,生成一个新的可调用对象,方便地调用函数对象。

      例如,我们有一个函数对象:
      void foo(int a, int b, int c) { std::cout << a << " " << b << " " << c << std::endl; }
      我们可以使用std::bind将它绑定到一些参数上:
      auto f = std::bind(foo, 1, 2, 3);
      这里,f是一个新的可调用对象,它绑定了foo函数和参数1、2、3。我们可以像调用原始函数对象一样调用它:
      f(); // 输出:1 2 3
      我们也可以只绑定部分参数:
      auto g = std::bind(foo, 1, std::placeholders::_1, 3);
      这里,std::placeholders::_1表示占位符,它表示在调用g时,第二个参数会被传递给foo函数。我们可以这样调用g:
      g(2); // 输出:1 2 3
      这就是std::bind的基本用法。它可以方便地将函数对象和参数绑定在一起,生成一个新的可调用对象。

      std::bind的优缺点

      优点:

      可以方便地实现函数对象的复用和参数的延迟绑定,从而提高代码的可读性和可维护性。

      缺点:

      可能会导致代码的复杂性增加,特别是当参数较多时,需要谨慎使用。

      代码示例

      #pragma once
      
      #include 
      #include 
      class A {
      public:
       bool TESTA(int, char*, int) { /* implementation */ }
      };
      
      class B {
      public:
       bool TESTB(std::function func) { /* implementation */ }
      };
      
      int main() {
       A objA;
       B objB;
       auto lambda = [](int a, char* b, int c) { /* implementation */ };
       objB.TESTB(lambda);
       objB.TESTB(std::bind(&A::TESTA, &objA, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
       return 0;
      }
    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>