整理c++ function和bind的常用用法

news/2025/3/28 8:35:16/文章来源:https://www.cnblogs.com/daaobeng1019/p/18784669

c++的function是一种函数包装器,可以保存其他可调用对象,如函数,lambada表达式,bind()表达式,成员函数等。bind可以生成函数的转发调用包装器。bind和function都定义在头文件<functional>里。

参考链接

  • cpp reference std::function
  • cpp reference std::bind

使用std::function绑定一个自由函数

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersvoid printValues(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}int main() {//绑定一个function对象到自由函数,function传入的函数返回值和参数列表需要和实际绑定的函数一样std::function<void(int,int,int)>  func = printValues;func(100, 200, 300);return 0;
}

使用std::function绑定一个lambda表达式

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersint main() {//绑定一个lambda表达式std::function<void(int,int)>  funcL = [](int a,int b) -> void{std::cout << "a = " << a << " b = " << b << std::endl;};funcL(123, 456);return 0;
}

使用std::function绑定一个类成员函数,推荐使用std::bind来绑定类的成员函数

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersstruct MyFoo
{int val;MyFoo(int i) : val(i) { std::cout << "MyFoo cons" << i << '\n'; }void printVal() const { std::cout << val << '\n'; }void printAddVal(int i) { std::cout << val + i << '\n'; }
};int main() {// 存储到成员函数的调用//因为成员函数在调用时,会隐式传入this指针,所以绑定时,需要传入一个MyFoo&参数//如果成员函数用const修饰,那么要传入const MyFoo&std::function<void(const MyFoo&)> my_foo_print = &MyFoo::printVal;MyFoo mfoo(27895);my_foo_print(mfoo);my_foo_print(30001122); //30001122被构造成MyFoo的对象std::function<void(MyFoo&, int)> my_foo_printadd = &MyFoo::printAddVal; my_foo_printadd(mfoo,20);//my_foo_printadd(46123,20);   //46123会被构造成为一个临时对象,临时对象不能绑定到const引用,编译会报错//使用std::bind来绑定,类的成员函数MyFoo mfoo2(54321);std::function<void(void)> my_foo_print2 = std::bind(&MyFoo::printVal, &mfoo2);my_foo_print2();std::function<void(int)> my_foo_printadd2 = std::bind(&MyFoo::printAddVal, &mfoo2, std::placeholders::_1);my_foo_printadd2(300);return 0;
}

使用std::bind,比较常用的就是绑定类成员函数或一个自由函数

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersvoid printValues(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}struct MyFoo
{int val;MyFoo(int i) : val(i) { std::cout << "MyFoo cons" << i << '\n'; }void printVal() const { std::cout << val << '\n'; }void printAddVal(int i) { std::cout << val + i << '\n'; }
};using namespace std::placeholders;int main()
{MyFoo foo(100);auto print = std::bind(&MyFoo::printVal, &foo);print();auto printAdd = std::bind(&MyFoo::printAddVal, &foo, _1);printAdd(200); //参数传入200,对应占位符_1auto printAdd2 = std::bind(&MyFoo::printAddVal, &foo, 50);printAdd2();    //参数固定传入50//传给printValues的第一个参数是display的第2个参数,30//printvalues的第二个参数是固定值20//printvalues的第3个参数是display的第1个参数,10auto display = std::bind(printValues, _2, 20, _1);display(10, 30);    //a = 10, b = 20, c = 30//传给printValues的第一个参数是display2的第3个参数,20//printvalues的第二个参数是display2的第一个参数,30//printvalues的第3个参数是display的第2个参数,10auto display2 = std::bind(printValues, _3, _1, _2);display2(30, 10, 20);    //a = 20, b = 30, c = 10return 0;
}

使用std::function定义一个函数类型,一般在给其他类提供一个callback类型时使用。

#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersvoid printValues(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}typedef std::function<void(int,int,int)> ShowFunc;
using Display = std::function<void(int,int,int)>;using namespace std::placeholders;int main()
{ShowFunc func = printValues;func(100, 200, 300);Display disp = printValues;disp(400, 500, 600);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/902354.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hook(钩子技术)

一.介绍 1.当代码执行到某行时,获取寄存器值和内存里的值,进行调试分析,例如hook明文包. 2.当代码执行到某行时,插入想执行的代码.例如迅雷拦截发包函数. 3.当代码执行到某行时,修改寄存器,达到某些篡改目的. 拿FishingKit这道题举例就是本来运行流程是: a--->b 而使用了H…

2024年1月Java项目开发指南20:windows下使用Nignx部署应用

命令 启动start nginx重新加载配置文件 nginx -s reload nginx -t修改配置后执行上面两个语句下载地址 https://nginx.org/en/download.html 部署Vue项目 1 打包Vue项目 得到dist文件件 2 启动Nginx,访问localhost 注意:Nginx需要占用80端口。 启动后访问localhost,成功后如…

Z3-solve 求解器(SMT求解器)解方程:

Int(name, ctx=None),创建一个整数变量,name是名字 Ints (names, ctx=None),创建多个整数变量,names是空格分隔名字 IntVal (val, ctx=None),创建一个整数常量,有初始值,没名字。 对于实数类型的API与整数类型一致,向量(BitVec)则稍有区别: Bitvec(name,bv,ctx=None),…

CSS 如何设置父元素的透明度而不影响子元素的透明度

CSS 如何设置父元素的透明度而不影响子元素的透明度CSS 如何设置父元素的透明度而不影响子元素的透明度 在 CSS 中,设置父元素的透明度(如通过 opacity 属性)会影响所有子元素的透明度,因为 opacity 是作用于整个元素及其内容的。如果想让父元素透明但不影响子元素的透明度…

ASE20N40-ASEMI工业电源专用ASE20N40

ASE20N40-ASEMI工业电源专用ASE20N40编辑:LL ASE20N40-ASEMI工业电源专用ASE20N40 型号:ASE20N40 品牌:ASEMI 封装:TO-220 最大漏源电流:20A 漏源击穿电压:400V 批号:最新 RDS(ON)Max:216mΩ 引脚数量:3 沟道类型:N沟道MOS管 封装尺寸:如图 特性:MOS管、N沟道MO…

GreatSQL 为何选择全表扫描而不选索引

GreatSQL 为何选择全表扫描而不选索引 1. 问题背景 在生产环境中,发现某些查询即使有索引,也没有使用索引,反而选择了全表扫描。这种现象的根本原因在于优化器评估索引扫描的成本时,认为使用索引的成本高于全表扫描。 2. 场景复现 2.1 环境信息机器 IP:192.168.137.120 Gr…

Profibus DP转EtherCAT实例展示欧姆龙PLC对接西门子变频器操作

一. 案例背景 在一个小型工厂,现场设备需求是Profibus DP转EtherCAT,两端设备分别是西门子变频器和欧姆龙PLC通讯,。为提高现场的工作效率,采纳捷米特JM-DPM-ECT网关模块来实现数据的互联互通。二.设备介绍 1.欧姆龙PLC 欧姆龙PLC是一种功能完善的紧凑型PLC,能为业界领先的…

bayaim-如何保证Redis中的数据都是热点数据?

——————————————————————————————————————————————————— ---- bayaim,申明:本文摘自:https://mp.weixin.qq.com/s?__biz=MzAwNDUxOTQ5MQ==&mid=2247623691&idx=1&sn=35e1b6e9206458f9fcd99e48bebccc13&…

translator

import streamlit as st import time import base64 from streamlit.components.v1 import html# 自定义CSS样式 def set_custom_style():st.markdown(""" <style>/* 页面背景:浅色渐变,提高可读性 */.main {background: linear-gradient(135deg, #E0F7…

AI+CRM纷享汇湖南株洲站圆满落幕

近日,由株洲工业和信息化局指导,湘数促会株洲联络处主办,华为云、纷享销客共同承办的“智变未来营销破局”暨企业CRM应用与发展趋势纷享汇在湖南株洲成功举办。此次活动吸引了近40位湘企高管参与,共同探讨企业数字化转型与营销破局的新路径。 一、华为云助力企业数字化转型…

postgresql 16版本之后使用yum方式下载

1.登录下载地址https://www.postgresql.org/download/linux/redhat/

bilibili 分段进度跳转

编辑好后重新投稿即可