C++中关于 <functional> 的使用

#include <functional> 是 C++ 标准库中的一个头文件,主要用于提供与函数对象、函数指针和函数适配器相关的功能

一:定义方式

 1. 定义和使用 std::function 和 Lambda 表达式

 2:使用 std::bind

你可以使用 std::bind 来绑定函数参数,并创建新的可调用对象。

补充1:std::bind 是 C++11 引入的一个函数适配器,可以将函数及其参数绑定在一起,生成一个新的可调用对象。它可以用于简化函数调用,特别是在需要部分应用或延迟调用的情况下。

相比直接调用封装到 std::function 中的好处在于可以提供更大的灵活性,尤其是在需要动态传递不同可调用对象的场景。以下是一些常见的实践应用示例,展示了封装的优势。

#include <iostream>
#include <functional>void Product(int x = 10) {std::cout << "Shuyuan: " << x << std::endl;
}int main() {// 使用 std::bind 绑定参数auto f1 = std::bind(Product, 5); // 绑定参数 5auto f2 = std::bind(Product);     // 使用默认参数f1(); // 输出: Shuyuan: 5f2(); // 输出: Shuyuan: 10// 可以使用 std::placeholders 来创建更复杂的绑定int val = 20;auto f3 = std::bind(Product, std::placeholders::_1); // 占位符f3(val); // 输出: Shuyuan: 20return 0;
}

 补充2:函数适配器是用于调整和转换函数接口的一种工具,使其能够与特定的调用约定或上下文兼容。在 C++ 中,函数适配器通常通过标准库中的 std::bindstd::functionstd::mem_fn 等实现。

常见的函数适配器

  1. std::bind:允许你固定某些参数,从而创建一个新的可调用对象。例如,将函数与某些参数绑定在一起,以便稍后调用。

  2. std::function:提供了一种类型安全的方式来存储任何可调用对象(函数指针、Lambda、函数对象等)。它允许你将不同类型的函数统一处理。

  3. std::mem_fn:用于将类成员函数转换为可调用对象,方便在 STL 算法中使用。

示例

#include <iostream>
#include <functional>void PrintSum(int a, int b) {std::cout << "Sum: " << a + b << std::endl;
}int main() {// 适配器,将第二个参数固定为 10auto boundFunction = std::bind(PrintSum, std::placeholders::_1, 10);boundFunction(5); // 输出: Sum: 15boundFunction(20); // 输出: Sum: 30return 0;
}

二:适用场景

1. 回调机制

在某些情况下,你可能需要将函数作为参数传递给其他函数,比如回调函数。通过使用 std::function,你可以很方便地传递不同的行为。

#include <iostream>
#include <functional>
#include <vector>// 一个接受回调的函数
void processValues(const std::vector<int>& values, std::function<void(int)> callback) {for (int value : values) {callback(value);}
}void myFunction(int x) {std::cout << "Processing value: " << x << std::endl;
}int main() {std::vector<int> values = {1, 2, 3, 4, 5};// 将 myFunction 作为回调传入processValues(values, myFunction);// 也可以传入 Lambda 表达式processValues(values, [](int x) {std::cout << "Lambda processing: " << x * 2 << std::endl;});return 0;
}

2. 存储不同类型的可调用对象

#include <iostream>
#include <functional>
#include <vector>int add(int a, int b) {return a + b;
}int multiply(int a, int b) {return a * b;
}int main() {std::vector<std::function<int(int, int)>> operations;operations.push_back(add);operations.push_back(multiply);int x = 5, y = 10;for (const auto& op : operations) {std::cout << "Result: " << op(x, y) << std::endl;}return 0;
}

3. 延迟执行和动态调度

#include <iostream>
#include <functional>
#include <queue>int main() {std::queue<std::function<void()>> tasks;// 将任务加入队列tasks.push([]() { std::cout << "Task 1 executed." << std::endl; });tasks.push([]() { std::cout << "Task 2 executed." << std::endl; });// 执行所有任务while (!tasks.empty()) {tasks.front()(); // 调用队列中的第一个任务tasks.pop();}return 0;
}

三:其他方法达到类似效果

1. 使用函数指针

#include <iostream>// 定义一个接受函数指针作为参数的函数
void process(int a, void (*func)(int)) {func(a);
}// 定义一个普通函数
void myFunction(int x) {std::cout << "Value: " << x << std::endl;
}int main() {process(10, myFunction); // 输出: Value: 10return 0;
}

 2. 使用模板

#include <iostream>// 定义一个接受任意可调用对象的函数
template <typename Func>
void process(int a, Func func) {func(a);
}int main() {// 使用 Lambda 表达式process(40, [](int x) {std::cout << "Lambda value: " << x << std::endl;});// 使用普通函数process(50, myFunction); // myFunction 可以直接传入return 0;
}

四:总结

  • std::function 定义:std::function<返回类型(参数类型...)>
  • 可以使用普通函数、Lambda 表达式、函数对象等。
  • 可以绑定参数,通过 std::bind 创建新的可调用对象。

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

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

相关文章

Axios 请求超时设置无效的问题及解决方案

文章目录 Axios 请求超时设置无效的问题及解决方案1. 引言2. 理解 Axios 的超时机制2.1 Axios 超时的工作原理2.2 超时错误的处理 3. Axios 请求超时设置无效的常见原因3.1 配置错误或遗漏3.2 超时发生在建立连接之前3.3 使用了不支持的传输协议3.4 代理服务器或中间件干扰3.5 …

WPF+MVVM案例实战(十五)- 实现一个下拉式菜单(上)

文章目录 1 案例效果2、图标资源下载3、功能实现1.文件创建2、菜单原理分析3、一级菜单两种样式实现1、一级菜单无子项样式实现2、一级菜单有子项样式实现 4、总结 1 案例效果 提示 2、图标资源下载 从阿里矢量素材官网下载需要的菜单图片&#xff0c;如下所示&#xff1a; …

【环境搭建】Apache ZooKeeper 3.8.4 Stable

软件环境 Ubuntu 20.04 、OpenJDK 11 OpenJDK 11&#xff08;如果已经安装&#xff0c;可以跳过这一步&#xff09; 安装OpenJDK 11&#xff1a; $ sudo apt-get update$ sudo apt-get install -y openjdk-11-jdk 设置 JAVA_HOME 环境变量&#xff1a; $ sudo gedit ~/.bash…

后台管理系统的通用权限解决方案(九)SpringBoot整合jjwt实现登录认证鉴权

1&#xff09;创建maven工程jjwt-login-demo&#xff0c;并配置其pom.xml文件如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-ins…

国考报名照片无法使用照片审核工具上传失败的解决办法

国考报名过程中&#xff0c;照片审核是至关重要的一步&#xff0c;但许多考生在上传照片时遇到了难题&#xff0c;导致无法继续报名&#xff0c;从而影响抢考场位置&#xff0c;下面就介绍如何快速完成照片处理、审核和上传过审的技巧。 一、国考报名照片基本要求首先&#xff…

vue中如何为不同功能设置不同的默认打印设置(设置不同的打印机)

浏览器自带的window.print 功能较简单&#xff0c;这里使用LODOP露肚皮打印 以下是vue2示例&#xff1a; 从官网中下载Lodop和C-Lodop官网主站安装包并安装到本地电脑可以全局搜索电脑找到安装文件LodopFuncs.js&#xff0c;也可以直接复制我贴出来的文件 //用双端口加载主JS…

数据库管理系统的ACID都各自是什么?

本文基于DBMS中ACID属性的概念&#xff0c;这些属性保证了数据库中执行事务时保持数据一致性、完整性和可靠性所。事务是访问并可能修改数据库内容的单一逻辑工作单元。交易使用读写操作访问数据。为了保持数据库的一致性&#xff0c;在事务前后&#xff0c;遵循某些属性。这些…

ssm基于vue搭建的新闻网站+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 [2 系统…

OB_GINS_day3

这里写目录标题 实现当前状态初始化实现预积分的初始化由于此时preintegration_options 是3&#xff08;也就是考虑odo以及earth rotation&#xff09;为预积分的容器添加需要积分的IMU积分因子接下来是添加新的IMU到preintegration中 实现当前状态初始化 这个state_curr的主要…

如何优化kafka和mysql处理百万级消息计算和落库

一.业务场景 最近业务需要&#xff0c;做了性能优化操作。百万级消息在kafka中秒级传输。cpu密集计算分钟级完成&#xff0c;然后在mysql中秒级落库.模型cpu计算提高了1倍&#xff0c;落表速度提高了5倍&#xff0c;2分钟内完成. 如下序列图&#xff1a; 业务系统A发送千级别…

深度学习基础知识-Batch Normalization(BN)超详细解析

一、背景和问题定义 在深层神经网络&#xff08;Deep Neural Networks, DNNs&#xff09;中&#xff0c;层与层之间的输入分布会随着参数更新不断发生变化&#xff0c;这种现象被称为内部协变量偏移&#xff08;Internal Covariate Shift&#xff09;。具体来说&#xff0c;由…

NLP算法工程师精进之路:顶会论文研读精华

1.学术能力培养 全部论文资料下载&#xff1a; 将论文和 GitHub 资源库匹配 papers with code https://paperswithcode.com/OpenGitHub 新项目快报Github pwc&#xff1a;https://github.com/zziz/pwc GitXiv&#xff1a;http://www.gitxiv.com/ 文章撰写 Overleaf [Autho…

从倍压整流到二极管钳位与限幅

何为倍压整流&#xff1f;这里直接引用“百度百科”解释&#xff0c;如下述。 在一些需用高电压、小电流的地方&#xff0c;常常使用倍压整流电路。倍压整流&#xff0c;可以把较低的交流电压&#xff0c;用耐压较高的整流二极管和电容器&#xff0c;“整”出一个较高的直流电…

Java项目实战II基于Java+Spring Boot+MySQL的工程教育认证的计算机课程管理平台(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着工程教…

uniapp开发小程序【简单的实现点击下拉选择性别功能】

一、展示效果 二、代码 <template><view><view class="form_box"><view class="item"

硅谷甄选(9)SKU模块

SKU模块 8.1 SKU静态 <template><el-card><el-table border style"margin: 10px 0px"><el-table-column type"index" label"序号" width"80px"></el-table-column><el-table-columnlabel"名称…

Flutter Color 大调整,需适配迁移,颜色不再是 0-255,而是 0-1.0,支持更大色域

在之前的 3.10 里&#xff0c; Flutter 的 Impeller 在 iOS 上支持了 P3 广色域图像渲染&#xff0c;但是当时也仅仅是当具有广色域图像或渐变时&#xff0c;Impeller 才会在 iOS 上显示 P3 的广色域的颜色&#xff0c;而如果你使用的是 Color API&#xff0c;会发现使用的还是…

动态威胁场景下赋能企业安全,F5推出BIG-IP Next Web应用防火墙

许多企业正面临由混合和多云环境运营复杂性所引发的危机&#xff0c;它们普遍耗巨资于物理和虚拟设备的持续维护、修补和升级上&#xff0c;而针对不同云环境下的应用部署则需要特有的技能来管理众多繁杂的工具和服务。为助力企业应对上述挑战&#xff0c;F5公司发布了BIG-IP N…

如何用Python同时抓取多个网页:深入ThreadPoolExecutor

背景介绍 在信息化时代&#xff0c;数据的实时性和获取速度是其核心价值所在。对于体育赛事爱好者、数据分析师和投注行业而言&#xff0c;能否快速、稳定地抓取到实时比赛信息显得尤为重要。特别是在五大足球联赛中&#xff0c;能够在比赛进行时获得比分、控球率等实时数据&a…

(转载)Tools for Learning LLVM TableGen

前提 最近在学习有关llvm的东西&#xff0c;其中TableGen占了一部分&#xff0c;所以想特意学习下TableGen相关的语法。这里找到了LLVM官网的一篇介绍TableGen的博客&#xff0c;学习并使用机器翻译为中文。在文章的最后也添加了一些学习TableGen的资源。 原文地址&#xff1…