首页 > 编程语言 >C++11 std::function与std::bind

C++11 std::function与std::bind

时间:2024-12-03 10:32:12浏览次数:8  
标签:std 11 函数 function bind 绑定 int

std::function与std::bind

 

std::function

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

例如

// 普通函数
int add(int a, int b){return a+b;} 

// lambda表达式
auto mod = [](int a, int b){ return a % b;}

// 函数对象类
struct divide{
    int operator()(int denominator, int divisor){
        return denominator/divisor;
    }
};


std::function<int(int ,int)>  a = add; 
std::function<int(int ,int)>  b = mod ; 
std::function<int(int ,int)>  c = divide(); 

 

 std::function 对象最大的用处就是在实现函数回调,使用者需要注意,它不能被用来检查相等或者不相等,但是可以与 NULL 或者 nullptr 进行比较。

 

std::bind

可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。std::bind主要有以下两个作用:

  • 将可调用对象和其参数绑定成一个仿函数;
  • 只绑定部分参数,减少可调用对象传入的参数。


绑定普通函数

double my_divide(double x, double y) {return x/y;}
auto fn_half = std::bind (my_divide, std::placeholders::_1, 2);  
std::cout << fn_half(10) << std::endl;     // my_divide(10, 2)

其中,std::placeholders::_1 为占位符,是绑定后的函数需要传入的参数。

普通函数做实参时,会隐式转换成函数指针。因此std::bind (my_divide, _1, 2)等价于std::bind (&my_divide, _1, 2);

 

绑定类的成员函数

class Bar {
public:
  void fun1(int x) {
    std::cout << "Bar::fun1(int) called with value: " << x << std::endl;
  }

  static void func2(string y) {
    std::cout << "Bar::fun2(int) called with value: " << y << std::endl;
  }
};

int main() {
  Bar obj;

  // 使用 std::function 绑定成员函数
  std::function<void(int)> func =
      std::bind(&Bar::fun1, &obj, std::placeholders::_1);

  // 调用绑定的成员函数
  func(10); // 输出: Member function called with value: 10

  // 或者使用 lambda 表达式
  std::function<void(int)> lambdaFunc = [&obj](int x) { obj.fun1(x); };

  // 调用 lambda
  lambdaFunc(20); // 输出: Member function called with value: 20

  // 绑定 static 成员函数
  std::function<void(string)> func2 =
      std::bind(&Bar::func2, std::placeholders::_1);
  func2("hello world");

  return 0;
}

提供了两种方式:

  1. 使用 bind 函数;
  2. 使用  lambda 表达式;
   

绑定一个引用参数

class Bar {
public:
  void fun1(int &x) {
    x += 10;
    std::cout << "Bar::fun1(int) called with value: " << x << std::endl;
  }
};

int main() {
  Bar obj;
  int value = 10;

  // 使用 std::function 绑定成员函数
  std::function<void(int)> func = std::bind(&Bar::fun1, &obj, std::ref(value));

  // 调用绑定的成员函数
  func(10); // 输出: Member function called with value: 20

  return 0;
}

使用  std::ref(value) 函数 来绑定 value 的引用,这样在调用 func 时,value 的值会被更新。

 

 

标签:std,11,函数,function,bind,绑定,int
From: https://www.cnblogs.com/chenny7/p/12089292.html

相关文章

  • 《痞子衡嵌入式半月刊》 第 112 期
    痞子衡嵌入式半月刊:第112期这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期。本期刊是开源项目(GitHub:JayHeng/pzh-mcu-bi-weekly),欢迎提交issue,投稿或推荐你知道的嵌入式那些事儿。上期回顾:《痞子衡嵌入式半月......
  • YOLOv11模型在K230开发板部署过程记录
           当您看到这篇文章时想必您已经完成了模型训练,这里以YOLOv11训练出来的pt模型为例给出模型在K230开发板的部署流程环境:windows11,ubuntu20.04(已安装python,pip),nncase2.9.0,K230开发板1、模型转换        将pt格式转化为onnx格式以便使用nncase工具链进行......
  • YOLOv11改进,YOLOv11添加SAConv可切换空洞卷积,二次创新C3k2结构
    摘要作者提出的技术结合了递归特征金字塔和可切换空洞卷积,通过强化多尺度特征学习和自适应的空洞卷积,显著提升了目标检测的效果。理论介绍空洞卷积(AtrousConvolution)是一种可以在卷积操作中插入“空洞”来扩大感受野的技术,更有效地捕捉到图像中的大范围上下文信息......
  • [luoguP11361/NOIP2024] 编辑字符串
    题意给出两个0/1字符串,每个字符串有一些位置被标记,无法交换。求通过任意多次的交换相邻元素操作能够使两个字符串最多多少位置相同。sol一道贪心题。显然交换相邻的操作可以使该字符串可以交换的一段任意排列。由于不同位置的贡献最大只为\(1\),因此在任何位置贡献都没有区......
  • Task04 :Variables and Functions
    变量在Python中,变量是用来存储数据的。它不需要像C语言中需要对变量的类型进行定义,Python会根据赋值自动确认变量的类型。变量的命名规则:必须以字母或下划线开头。只能包含数字、字母、下划线。变量只是一个名称,用于与数据进行联系。定义变量时,现在内存空间中申请一块地......
  • 题解:P11217 【MX-S4-T1】「yyOI R2」youyou 的垃圾桶
    链接https://www.luogu.com.cn/problem/P11217分析先不考虑维护垃圾桶的攻击力,假设我们已经知道了所有垃圾桶的攻击力。翻倍操作可以用左移(<<)实现。首先先计算出所有垃圾桶的伤害值,然后看看能抗几个整轮。然后考虑不能抗的情况。由于所有垃圾桶的攻击力都为正数,所以可以二......
  • COMP09110 Python for Network Engineers
    FINALCOURSEWORKINSTRUCTIONS[50%offinalmark]COMP09110PythonforNetworkEngineersThistaskisdesignedtotesttheabilitytoputintopracticetheknowledgegainedduringyourmodule.Yourtaskwillbetocreateasimplevideogameserverthats......
  • linux-11 关于shell(十)执行入口、模数
      比如说在系统刚刚启动的时候,这里要求我们进行登录,我输入用户名,然后输入密码,就可以正常登录,正常登录以后,会显示什么,叫命令提示符对吧?叫做prompt,我们把它称为叫命令提示符。如下图,那就意味着我们在底下可以输入命令了,对吧?既然叫命令提示符,那么所输入的一定得是命令,要注......
  • 【C++】右值引用全面揭秘:解锁 C++11 的性能革命与移动语义奥秘!
    文章目录右值和左值的基本概念左值引用和右值引用右值引用的主要用途移动语义只有拷贝构造和赋值重载而没有移动语义的传值返回增加移动构造和移动赋值的传值返回引用折叠与完美转发C++11引入了右值引用,这是C++语言的一个重要特性,目的是为了提高程序的性能,尤其在对......
  • UniApp 微信小程序请求接口报错:request:fail errcode:10011 的原因分析与解决方案
    UniApp微信小程序请求接口报错:request:failerrcode:10011的原因分析与解决方案在使用UniApp开发微信小程序时,我们可能会遇到一些请求接口的错误,特别是request:failerrcode:10011cronet_error_code:0error_msg:networkchange,cancelalltask这样的错误信息。这......