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/8/13 13:48:39 阅读更多 →
用友U8数据库核心表结构与业务关联解析(附常用查询SQL)

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

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

2026/8/13 13:47:39 阅读更多 →
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/8/13 13:47:39 阅读更多 →

最新新闻

OpCore-Simplify 黑苹果配置工具实测:30分钟从零生成 OpenCore EFI 的完整教程

OpCore-Simplify 黑苹果配置工具实测:30分钟从零生成 OpenCore EFI 的完整教程

OpCore-Simplify 黑苹果配置工具实测:30分钟从零生成 OpenCore EFI 的完整教程 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 凌晨一点&a…

2026/8/13 14:47:33 阅读更多 →
告别传统编码:探索Mito可视化数据处理的革命性方案

告别传统编码:探索Mito可视化数据处理的革命性方案

告别传统编码:探索Mito可视化数据处理的革命性方案 【免费下载链接】mito Jupyter extensions that help you write code faster: Context aware AI Chat, Autocomplete, and Spreadsheet 项目地址: https://gitcode.com/gh_mirrors/mi/mito 想象一下&#x…

2026/8/13 14:47:33 阅读更多 →
LXMusic音源配置全攻略:一个播放器聚合全网音乐,免费听歌从此不难

LXMusic音源配置全攻略:一个播放器聚合全网音乐,免费听歌从此不难

LXMusic音源配置全攻略:一个播放器聚合全网音乐,免费听歌从此不难 【免费下载链接】LXMusic音源 lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/guoyue2010/lxmusic- 你是不是也经历过这样的场景&…

2026/8/13 14:47:33 阅读更多 →
一个下午跑通 Meep:免费开源 FDTD 电磁仿真从安装到逆设计实战

一个下午跑通 Meep:免费开源 FDTD 电磁仿真从安装到逆设计实战

一个下午跑通 Meep:免费开源 FDTD 电磁仿真从安装到逆设计实战 【免费下载链接】meep free finite-difference time-domain (FDTD) software for electromagnetic simulations 项目地址: https://gitcode.com/gh_mirrors/me/meep 如果你正在研究光子晶体、超…

2026/8/13 14:47:33 阅读更多 →
AWS IAM权限提升漏洞深度解析与防御实战指南

AWS IAM权限提升漏洞深度解析与防御实战指南

1. 项目概述:为什么IAM权限提升是AWS安全的命门? 在云上搞安全,如果你只盯着防火墙和入侵检测,那可能连门都没摸到。我干了十多年云安全,处理过无数起安全事件,可以很负责任地告诉你,超过70%的云…

2026/8/13 14:47:33 阅读更多 →
music-api音乐接口快速上手:5分钟获取四大平台歌曲播放地址

music-api音乐接口快速上手:5分钟获取四大平台歌曲播放地址

music-api音乐接口快速上手:5分钟获取四大平台歌曲播放地址 【免费下载链接】music-api Music API 项目地址: https://gitcode.com/gh_mirrors/mu/music-api 一句话定位:music-api音乐接口是一个基于 PHP 的开源小工具,用一套统一的请求…

2026/8/13 14:46:32 阅读更多 →

日新闻

Visual Studio新建项目解决方案为空:系统性排查与修复指南

Visual Studio新建项目解决方案为空:系统性排查与修复指南

1. 问题现象与本质剖析如果你是一位.NET开发者,或者正准备踏入这个领域,那么Visual Studio(后面简称VS)绝对是你绕不开的伙伴。但有时候,这个伙伴会跟你开一个不大不小的玩笑:你满怀期待地点击“创建新项目…

2026/8/13 0:00:09 阅读更多 →
长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

说实话,每次提起“长春建设厅网站”这几个字,我心里都挺有感触的。不是因为它有多高大上,也不是因为那里藏着什么不可告人的秘密,恰恰相反,是因为它太“接地气”了,或者说,它是咱们普通人想要在这个城市好好生活、安稳买房时,必须得翻过的一座“数据山”。很多新朋友第…

2026/8/13 0:00:09 阅读更多 →
Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾为Windows家庭版无法支持多用户远程桌面…

2026/8/13 0:00:09 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/13 10:41:52 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/13 10:41:51 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/13 10:41:50 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/13 10:41:49 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/13 10:41:49 阅读更多 →