C++ std::function 解读
前言std::function大家用过吗它是C11引入的一个新特性。今天我们从原理、应用实例等方面对std::fucntion进行深度剖析。目录一、基本定义与使用二、底层机制三、典型应用场景一、基本定义与使用std::function是一种多态函数包装器它定义在functional头文件中可以存储、复制和调用任何可调用目标Callable包括普通函数、成员函数、函数对象Functor、lambda 表达式等。std::function 使用统一的方式来封装不同类型的可调用对象使其可以像普通函数一样被调用和传递。std::function语法如下std::functionReturnType(Args...) func_name;ReturnType表示函数的返回类型Args...表示函数的参数类型列表。例如声明一个可以接受两个int参数并返回int的函数包装器std::functionint(int, int) func1;上述声明创建的是一个空的std::function对象func1还没有包装任何可调用对象。接下来我们可以通过赋值或直接初始化将一个可调用对象包装到其中例如int add(int a, int b) { return a b; } func1 add; // 将普通函数 add 包装到 func1 中 func1(1,2);std::function也可以包装Lambda表达式如int offset 10; func1 [offset](int a, int b) { return a b offset; }; func1(1,2);二、底层机制std::function的底层核心机制是类型擦除Type Erasure它能够在编译期抹除具体可调用对象的类型在运行期通过统一的虚函数机制进行调用。1) 核心数据结构std::function 内部通常包含两个关键成员class functionR(Args...) { // 1. 管理接口vtable 指针 __function_base::__manager_type* __manager_; // 2. 数据存储联合体/缓冲区 union { // 小对象优化缓冲区通常 16~24 字节 mutable char __buf[16]; // 或指向堆内存的指针 void* __f; }; };2) vtable机制编译期没有办法提前知道你要存入std::function的是 lambda表达式、普通函数、还是自定义的仿函数(函数对象)因此它实现了一个管理器接口类似虚函数表struct __manager_type { // 克隆/销毁/移动等管理操作 void* (*__clone)(const void*); // 拷贝构造 void (*__destroy)(void*); // 析构 void (*__move)(void*, void*); // 移动构造 // 实际调用跳转 R (*__invoke)(const void*, Args...); // 调用 };当你执行std::functionvoid() f [x42]{ ... };时编译器为该 lambda 类型生成一个静态的__manager_type实例将 lambda 对象存入__buf小对象或堆内存__manager_指向该静态 vtable三、典型应用场景场景一回调函数最经典当模块 A 需要通知模块 B但 B 的具体形式在编译期不确定时#include functional #include iostream #include vector class Button { std::functionvoid() onClick_; // 存储任意无参无返回的可调用对象 public: void setOnClick(std::functionvoid() cb) { onClick_ std::move(cb); } void click() const { if (onClick_) onClick_(); } }; int main() { Button btn; int count 0; // 可以绑定 Lambda带捕获 btn.setOnClick([count] { count; std::cout Clicked count times\n; }); btn.click(); // Clicked 1 times btn.click(); // Clicked 2 times return 0; }通过std::function我们可以编写出更通用的代码避免为每种可能的回调函数类型编写重载版本。场景二线程池/任务队列各任务类型不同但都需要统一入队和执行#include functional #include queue #include thread #include vector #include future class ThreadPool { std::queuestd::functionvoid() tasks_; // 统一任务类型 std::vectorstd::thread workers_; // ... 互斥锁、条件变量省略 public: // 提交任意任务返回 future 获取结果 template typename Func, typename... Args auto submit(Func f, Args... args) - std::futuredecltype(f(args...)) { using Ret decltype(f(args...)); // 将任务打包成 std::functionvoid()类型擦除 auto task std::make_sharedstd::packaged_taskRet()( std::bind(std::forwardFunc(f), std::forwardArgs(args)...) ); std::futureRet res task-get_future(); { // std::lock_guardstd::mutex lock(mutex_); tasks_.emplace([task]() { (*task)(); }); // 存入队列 } // condition_.notify_one(); return res; } };上述示例中std::queuestd::functionvoid()使得不同签名、不同捕获的 Lambda 都能排队等待执行。写在最后虽然std::function提供了高度的灵活性和通用性但它也引入了一定的性能开销如 间接调用开销、内存分配开销。在一些性能要求不高的场景下这种开销可以忽略不计但在关键路径上需要大家根据实际情况来权衡使用。

相关新闻

PhotoGIMP:把 Photoshop 的界面和快捷键,整套搬进免费的 GIMP 3

PhotoGIMP:把 Photoshop 的界面和快捷键,整套搬进免费的 GIMP 3

PhotoGIMP:把 Photoshop 的界面和快捷键,整套搬进免费的 GIMP 3 【免费下载链接】PhotoGIMP A Patch for GIMP 3 for Photoshop Users 项目地址: https://gitcode.com/GitHub_Trending/ph/PhotoGIMP 订阅到期、账单提醒接踵而至的那个下午&#x…

2026/10/17 23:31:21 阅读更多 →
用友U8数据库核心表结构与业务关联解析(附常用查询SQL)

用友U8数据库核心表结构与业务关联解析(附常用查询SQL)

用友U8是典型的SQL Server数据库架构,理解其表结构是实施顾问和二次开发者的基本功。本文从实战出发,梳理财务、供应链、生产制造三大模块的核心表及关联关系,配合可直接使用的SQL查询示例。背景说明用友U8采用SQL Server数据库,数…

2026/10/17 13:08:59 阅读更多 →
Linux动态链接库依赖问题深度解析:从libssl.so.1.1缺失到OpenSSL版本兼容性实战

Linux动态链接库依赖问题深度解析:从libssl.so.1.1缺失到OpenSSL版本兼容性实战

1. 项目概述:当“依赖”成为拦路虎 如果你在Linux环境下折腾过软件,尤其是那些需要自己编译或者从第三方渠道获取的二进制包,那么对屏幕上弹出的“error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No…

2026/10/18 9:25:36 阅读更多 →

最新新闻

STM32单片机 2引脚按键

STM32单片机 2引脚按键

按键:常见的输入设备,按下导通,松手断开按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动为防止按键按一下,单片机却反应多次的现象,因此要…

2026/10/19 1:12:12 阅读更多 →
MiniOB 完整导读:不到 10 万行代码,把 B+ 树索引、事务和 SQL 执行链路一次讲透

MiniOB 完整导读:不到 10 万行代码,把 B+ 树索引、事务和 SQL 执行链路一次讲透

MiniOB 完整导读:不到 10 万行代码,把 B 树索引、事务和 SQL 执行链路一次讲透 【免费下载链接】miniob MiniOB is a compact database that assists developers in understanding the fundamental workings of a database. 项目地址: https://gitcode…

2026/10/19 1:12:12 阅读更多 →
STM32单片机 RCC与GPIO

STM32单片机 RCC与GPIO

一,外设 (Peripherals)外设是指与主处理器(CPU)连接的硬件模块,这些模块提供了扩展功能,使得单片机可以与外部设备进行交互。常见的外设包括:GPIO(通用输入/输出):用于控…

2026/10/19 1:12:12 阅读更多 →
Stable-Audio-Tools 入门指南:条件音频生成模型的训练、推理与 Gradio 界面跑通

Stable-Audio-Tools 入门指南:条件音频生成模型的训练、推理与 Gradio 界面跑通

Stable-Audio-Tools 入门指南:条件音频生成模型的训练、推理与 Gradio 界面跑通 【免费下载链接】stable-audio-tools Generative models for conditional audio generation 项目地址: https://gitcode.com/GitHub_Trending/st/stable-audio-tools Stable-Au…

2026/10/19 1:12:12 阅读更多 →
3步上手Nemotron-3-Diarization:generate与generate_stream说话人分离调用实战教程

3步上手Nemotron-3-Diarization:generate与generate_stream说话人分离调用实战教程

【免费下载链接】Nemotron-3-Diarization 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/Nemotron-3-Diarization 点击查看 免费下载 Nemotron-3-Diarization 是一款基于 MLX 框架的说话人分离(Speaker Diarization)模型&…

2026/10/19 1:12:12 阅读更多 →
2022 年 12 月青少年软编等考 C 语言七级真题解析

2022 年 12 月青少年软编等考 C 语言七级真题解析

目录 T1. 走迷宫 思路分析 T2. 重建二叉树 思路分析 T3. 快速堆猪 思路分析 T4. 表达式 表达式树 表达式求值 思路分析 T1. 走迷宫 题目链接:SOJ D1233 一个迷宫由 R R R 行 C C C 列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。给定一个迷宫,求从…

2026/10/19 1:11:12 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →