当前位置: 首页 > article >正文

常用函数库之 - std::function

std::function 是 C++11 引入的通用可调用对象包装器,用于存储、复制和调用任意符合特定函数签名的可调用对象(如函数、lambda、函数对象等)。以下是其核心要点及使用指南:


​核心特性​

  • ​类型擦除​

可包装任意可调用对象,只要其调用签名与模板参数匹配。

例如:std::function<int(int, int)> 可存储普通函数、lambda、std::bind 表达式等,只要它们接受两个 int 参数并返回 int

  • ​灵活性​

比函数指针更通用,支持成员函数、带状态的函数对象等。

#include <functional>
#include <iostream>void print(int x) { std::cout << x << std::endl; }struct Functor {void operator()(int x) const { std::cout << x << std::endl; }
};int main() {std::function<void(int)> f1 = print;          // 普通函数std::function<void(int)> f2 = Functor();       // 函数对象std::function<void(int)> f3 = [](int x) {      // Lambdastd::cout << x << std::endl;};f1(42);  // 输出 42f2(42);  // 输出 42f3(42);  // 输出 42
}
  • ​成员函数绑定​

需结合 std::bind 或 Lambda 绑定对象实例:

class MyClass {
public:void method(int x) { std::cout << x << std::endl; }
};int main() {MyClass obj;// 使用 std::bindstd::function<void(int)> f1 = std::bind(&MyClass::method, &obj, std::placeholders::_1);// 使用 Lambdastd::function<void(int)> f2 = [&obj](int x) { obj.method(x); };f1(42);  // 输出 42f2(42);  // 输出 42
}

​使用注意事项​

  • ​空状态检查​

调用空的 std::function 会抛出 std::bad_function_call

检查是否可调用:

std::function<void(int)> f;
if (f) {  // 检查是否非空f(42);
}
  • ​性能开销​

存在类型擦除带来的间接调用开销(类似虚函数调用),通常适用于非性能敏感场景。

对比模板的高效性:

template <typename Callable>
void call(Callable&& f, int x) { f(x); }  // 无运行时开销,适合高频调用
  • ​类型兼容性​

参数和返回类型支持隐式转换:

void func(double x) { std::cout << x << std::endl; }
std::function<void(int)> f = func;
f(42);  // int 隐式转为 double,输出 42.0
  • ​不可比较性​

std::function 对象无法直接比较是否包装同一可调用对象:

std::function<void()> f1 = [] {};
std::function<void()> f2 = [] {};
// if (f1 == f2) { ... }  // 错误:operator== 未定义

​适用场景​

  • ​回调机制​

事件处理、异步操作等需动态注册回调的场景:

class Button {
public:void setOnClick(std::function<void()> onClick) {onClick_ = std::move(onClick);}void click() { if (onClick_) onClick_(); }
private:std::function<void()> onClick_;
};
  • ​策略模式​

运行时动态切换算法或行为:

class Processor {
public:using Algorithm = std::function<int(int, int)>;void setAlgorithm(Algorithm algo) { algo_ = algo; }int process(int a, int b) { return algo_ ? algo_(a, b) : 0; }
private:Algorithm algo_;
};
  • ​函数组合​

实现高阶函数(如函数适配器):

auto compose(std::function<int(int)> f, std::function<int(int)> g) {return [f, g](int x) { return f(g(x)); };
}

​总结​

  • ​优势​​:类型安全、灵活性高,适合需要动态绑定可调用对象的场景。
  • ​局限​​:运行时开销较高,无法直接比较包装的内容。
  • ​替代方案​​:在性能关键代码中,优先考虑模板或函数指针。

相关文章:

常用函数库之 - std::function

std::function 是 C11 引入的通用可调用对象包装器&#xff0c;用于存储、复制和调用任意符合特定函数签名的可调用对象&#xff08;如函数、lambda、函数对象等&#xff09;。以下是其核心要点及使用指南&#xff1a; ​​核心特性​​ ​​类型擦除​​ 可包装任意可调用对…...

php执行系统命令的四个常用函数

php执行系统命令有四个常用函数&#xff1a;1.exec()执行命令并返回最后一行输出&#xff0c;可传数组获取全部结果&#xff1b;2.shell_exec()返回完整输出结果&#xff0c;适合一次性获取&#xff1b;3.system()直接输出命令结果&#xff0c;可接收状态码&#xff1b;4.权限控…...

力扣-17.电话号码的字母组合

题目描述 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 class Solution {List<String> res new ArrayList<…...

基于SpringBoot解决RabbitMQ消息丢失问题

基于SpringBoot解决RabbitMQ消息丢失问题 一、RabbitMQ解决消息丢失问题二、方案实践1、在生产者服务相关配置2、在消费者服务相关配置 三、测试验证1、依次启动RabbitMQ、producer(建议先清空队列里面旧的测试消息再启动consumer)和consumer2、在producer中调用接口&#xff0…...

免费插件集-illustrator插件-Ai插件-随机填色

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;实现路径随机填色。首先从下载网址下载这款插件https://download.csdn.net/download/m0_67316550/87890501&#…...

使用 Unstructured 开源库快速入门指南

引言 本文将介绍如何使用 Unstructured 开源库&#xff08;GitHub&#xff0c;PyPI&#xff09;和 Python&#xff0c;在本地开发环境中将 PDF 文件拆分为标准的 Unstructured 文档元素和元数据。这些元素和元数据可用于 RAG&#xff08;检索增强生成&#xff09;应用、AI 代理…...

白银6月想法

一、市场回顾 2025年5月&#xff0c;SHFE白银主力合约总体呈现出震荡偏强的运行格局。从2025年5月1日至2025年5月30日&#xff0c;白银期货价格整体运行在7944元至8342元区间内&#xff0c;最高价出现在5月22日的8342.0元&#xff0c;最低价则为5月15日的7944元。最终在5月30日…...

OpenCV 滑动条调整图像对比度和亮度

一、知识点 1、int createTrackbar(const String & trackbarname, const String & winname, int * value, int count, TrackbarCallback onChange 0, void * userdata 0); (1)、创建一个滑动条并将其附在指定窗口上。 (2)、参数说明: trackbarname: 创建的…...

船舶事故海上搜救VR情景演练全场景 “复刻”,沉浸式救援体验​

船舶事故海上搜救 VR 情景演练系统的一大核心优势&#xff0c;便是能够全场景 “复刻” 海上事故&#xff0c;为使用者带来沉浸式的船舶事故海上搜救 VR 情景演练体验。​ 在船舶事故海上搜救 VR 情景演练的事故场景模拟方面&#xff0c;系统几乎涵盖了所有常见的船舶事故类型。…...

使用Caddy在Ubuntu 22.04上配置HTTPS反向代理

使用Caddy在Ubuntu 22.04上配置HTTPS反向代理(无域名/IP验证+密码保护) 一、 环境说明 环境说明:测试环境,生产环境请谨慎OS: Ubuntu 22.04.1 LTSCaddy版本:v2.10.0服务器IP: 192.168.3.88(内网)公网IP: 10.2.3.11(测试虚拟)代理端口: 9080后端服务: http://192.168.3…...

无人机目标检测与语义分割数据集(猫脸码客)

UAV 无人机数据集&#xff1a;驱动无人机配送研究迈向新高度 在科技浪潮的迅猛推动下&#xff0c;无人机配送这一新兴物流模式正以前所未有的态势&#xff0c;悄然改变着人们的生活图景。为深入挖掘并优化无人机配送技术&#xff0c;名为 UAV Delivery 的无人机数据集应运而生…...

Web设计之登录网页源码分享,PHP数据库连接,可一键运行!

HTML 页面结构&#xff08;index.html&#xff09; 1. 流星雨动态背景 2. 主体界面&#xff08;包含登录和注册表单&#xff09; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Cursor + Claude 4:微信小程序流量主变现开发实战案例

前言 随着微信小程序生态的日益成熟&#xff0c;越来越多的开发者开始关注如何通过小程序实现流量变现。本文将详细介绍如何使用Cursor编辑器结合Claude 4 AI助手&#xff0c;快速开发一个具备流量主变现功能的微信小程序&#xff0c;并分享实际的开发经验和变现策略。 项目…...

㊗️高考加油

以下是极为详细的高考注意事项清单&#xff0c;涵盖考前、考中、考后全流程&#xff0c;建议逐条核对&#xff1a; 一、考前准备 1. 证件与物品 必带清单&#xff1a; 准考证&#xff1a;打印2份&#xff08;1份备用&#xff09;&#xff0c;塑封或夹在透明文件袋中防皱湿。身…...

Redis Key过期策略

概述 Redis的Key过期策略是其内存管理系统的核心组成部分&#xff0c;主要包括「被动过期」、「主动过期」和「内存淘汰」三个机制。其中「内存淘汰」相关内容已经在上一篇「Redis内存淘汰策略」中进行了详细的讲解&#xff0c;有信兴趣的同学可以在回顾上一篇文章。本文将着重…...

【C/C++】实现固定地址函数调用

在 C 里&#xff0c;函数地址在程序运行期间通常是固定的&#xff0c;不过在动态链接库&#xff08;DLL&#xff09;或者共享库&#xff08;SO&#xff09;中&#xff0c;函数地址可能会因为地址空间布局随机化&#xff08;ASLR&#xff09;而改变。所以我们想要通过地址直接调…...

多模态大语言模型arxiv论文略读(109)

Math-PUMA: Progressive Upward Multimodal Alignment to Enhance Mathematical Reasoning ➡️ 论文标题&#xff1a;Math-PUMA: Progressive Upward Multimodal Alignment to Enhance Mathematical Reasoning ➡️ 论文作者&#xff1a;Wenwen Zhuang, Xin Huang, Xiantao Z…...

性能优化笔记

性能优化转载 https://www.cnblogs.com/tengzijian/p/17858112.html 性能优化的一般策略及方法 简言之&#xff0c;非必要&#xff0c;不优化。先保证良好的设计&#xff0c;编写易于理解和修改的整洁代码。如果现有的代码很糟糕&#xff0c;先清理重构&#xff0c;然后再考…...

bat批量去掉本文件夹中的文件扩展名

本文本夹内 批量去掉本文件夹中的文件扩展名 假如你有一些文件&#xff0c;你想去掉他们的扩展名 有没有方便的办法呢 今天我们就分享一种办法。 下面&#xff0c;就来看看吧。 首先我们新建一个记事本&#xff0c;把名字改为&#xff0c;批量去掉本文件夹中的文件扩展名.txt 然…...

基于ROS2,撰写python脚本,根据给定的舵-桨动力学模型实现动力学更新

提问 #! /usr/bin/env python3from control_planner import usvParam as P from control_planner.courseController import courseLimitationimport tf_transformations # ROS2没有自带tf.transformations, 需装第三方库 import rclpy from rclpy.node import Node from pid_…...

Scrapy爬虫教程(新手)

1. Scrapy的核心组成 引擎&#xff08;engine&#xff09;&#xff1a;scrapy的核心&#xff0c;所有模块的衔接&#xff0c;数据流程梳理。 调度器&#xff08;scheduler&#xff09;&#xff1a;本质可以看成一个集合和队列&#xff0c;里面存放着一堆即将要发送的请求&#…...

数据可视化大屏案例落地实战指南:捷码平台7天交付方法论

分享大纲&#xff1a; 1、落地前置&#xff1a;数据可视化必备的规划要素 2、数据可视化双路径开发 3、验证案例&#xff1a;数据可视化落地成效 在当下数字化转型浪潮中&#xff0c;数据可视化建设已成为关键环节。数据可视化大屏的落地&#xff0c;成为企业数据可视化建设的难…...

第五篇:Go 并发模型全解析——Channel、Goroutine

第五篇:Go 并发模型全解析——Channel、Goroutine 一、序章:Java 的并发往事 在 Java 世界中,说到“并发”,你可能立马想到以下名词:Thread、Runnable、ExecutorService、synchronized、volatile。再复杂点,ReentrantLock、CountDownLatch、BlockingQueue 纷纷登场,仿…...

锁的艺术:深入浅出讲解乐观锁与悲观锁

在多线程和分布式系统中&#xff0c;数据一致性是一个核心问题。锁机制作为解决并发冲突的重要手段&#xff0c;被广泛应用于各种场景。乐观锁和悲观锁是两种常见的锁策略&#xff0c;它们在设计理念、实现方式和适用场景上各有特点。本文将深入探讨乐观锁和悲观锁的原理、实现…...

在网页加载时自动运行js的方法(2025最新)

在网页加载时自动运行JavaScript方法有多种实现方式&#xff0c;以下是常见的几种方法&#xff1a; 1. ​​使用 DOMContentLoaded 事件​​ 当初始HTML文档完全加载和解析后触发&#xff08;无需等待图片等资源加载&#xff09;&#xff1a; document.addEventListener(DOMC…...

在Windows下编译出llama_cpp_python的DLL后,在虚拟环境中使用方法

定位编译生成的文件 在VS2022编译完成后&#xff0c;在构建目录&#xff08;如build/Release或build/Debug&#xff09;中寻找以下关键文件&#xff1a; ggml.dll、ggml_base.dll、ggml_cpu.dll、ggml_cuda.dll、llama.dll&#xff08;核心动态链接库&#xff09; llama_cp…...

CSS radial-gradient函数详解

目录 基本语法 关键参数详解 1. 渐变形状&#xff08;Shape&#xff09; 2. 渐变大小&#xff08;Size&#xff09; 3. 中心点位置&#xff08;Position&#xff09; 4. 颜色断点&#xff08;Color Stops&#xff09; 常见应用场景 1. 基本圆形渐变 2. 椭圆渐变 3. 模…...

n8n 自动化平台 Docker 部署教程(附 PostgreSQL 与更新指南)

n8n 自动化平台 Docker 部署教程&#xff08;附 PostgreSQL 与更新指南&#xff09; n8n 是一个强大的可视化工作流自动化工具&#xff0c;支持无代码或低代码地集成各种服务。本文将手把手教你如何通过 Docker 快速部署 n8n&#xff0c;并介绍如何使用 PostgreSQL、设置时区以…...

关于datetime获取时间的问题

import datetime print(datetime.now())如果用上述代码&#xff0c;会报错&#xff1a; 以下才是正确代码&#xff1a; from datetime import datetime print(datetime.now()) 结果&#xff1a; 如果想格式化时间&#xff0c;使用代码&#xff1a; from datetime import da…...

前端面试五之vue2基础

1.属性绑定v-bind&#xff08;&#xff1a;&#xff09; v-bind 是 Vue 2 中用于动态绑定属性的核心指令&#xff0c;它支持多种语法和用法&#xff0c;能够灵活地绑定 DOM 属性、组件 prop&#xff0c;甚至动态属性名。通过 v-bind&#xff0c;可以实现数据与视图之间的高效同…...