C++可调用对象全解析:std::function与std::bind底层原理及实战应用
在C的开发工作里可调用对象是我最早觉得“用得爽、但讲不清”的一组概念。十多年前我写一个命令分发模块各种动作函数的签名五花八门靠函数指针硬凑适配层代码里全是长着不同脸的包装函数。后来切换到 C11有了std::function 包装和std::bind 参数适配回调体系才真正变得轻松。这两个工具一个负责把不同形态的可调用对象统一装进同一个签名里一个负责把已有函数的参数提前绑定、顺序重排甚至丢弃多余的调用参数。这篇文章想把这些工具背后的机制、实际工作中的典型场景以及踩过的坑一并写清楚。适合对象是已经用过 lambda、但还没系统梳理过 function 和 bind 底层原理的 C 开发者如果你正在设计回调接口、任务队列或事件分发器这篇内容可以直接拿来参考。1. 先理清可调用对象到底有多少种1.1 函数指针、成员函数指针与仿函数从 C 语言时代开始函数指针就是最原始的回调形态。声明一个void (*cb)(int)把函数地址传出去另一方保存后再调用。函数指针的局限很明显它只能指向无状态的普通函数无法携带上下文签名一旦不匹配就得再写一层适配函数。C98 时代出现了函数对象也叫仿函数。重载operator()的类就是一个函数对象。相比函数指针它的最大优势是可以携带成员状态比如统计调用次数、记录上下文信息同时因为类型没有被擦除编译器可以轻易把operator()内联掉性能往往比间接调用好。劣势在于写起来繁琐定义一个回调就要写一个类如果只是为了捕获一个局部变量写起来非常痛苦。还有一类容易被忽略的成员函数指针。void (Foo::*ptr)(int)这类东西并不完整它必须和一个对象实例配合才能调用。比如(obj.*ptr)(42)。这意味着如果要把成员函数当作可调用对象传给某个接口还必须把对象也一并传过去。这正是 std::bind 后来解决得最好的问题之一。1.2 lambda 与 bind 表达式也是可调用对象C11 引入了 lambda本质上是语法糖编译器会为它生成一个匿名的函数对象类。捕获列表中的变量会成为这个类的成员变量函数体就是重载后的operator()。所以 lambda 和仿函数在底层是一回事只是在写法上大大简化了局部回调的创建成本。std::bind 表达式同样返回一个函数对象。这个函数对象内部保存了原函数和已经绑定的参数调用时通过占位符把外部实参映射到正确位置。从**可以被调用**这个角度看函数指针、成员函数指针、仿函数、lambda、bind 表达式都是可调用对象。它们形态差异很大但在某些场景下我们想用一个统一的东西去承接它们于是就有了 std::function。1.3 接口边界为什么要统一签名你可能会说直接用模板不就行了模板确实能接收任意可调用对象而且在编译期保留完整类型和优化空间。但模板有一个问题它的类型信息会向所有调用方扩散。一旦某个接口声明为模板所有调用该接口的地方都得变成模板或显式传类型没法做成非模板的运行时接口更没法把不同类型的回调放进同一个容器里。std::function 解决的正是这个痛点。它只暴露一个固定签名比如std::functionint(int)内部却可以存放任意形态、参数匹配的可调用对象。这在设计业务回调、事件总线、命令表、任务队列时特别有用——你的接口只需要面对一个统一的类型具体实现由调用方负责。在设计回调接口时有个经验泛型库内部多用模板保持零开销系统边界、插件接口、容器存储等需要运行时分发的场合用 std::function 换取形态统一。2. std::function能装下所有可调用的盒子2.1 类型擦除到底是怎么实现的std::function 的模板参数是调用签名而不是目标对象类型。比如std::functionvoid(int)的模板参数是void(int)但你传入的 lambda、仿函数、函数指针类型五花八门。它之所以能放下各种类型靠的是 C 里经典的类型擦除手法继承 虚函数 模板派生类。可以这样理解它的内部结构function 对象里保存了一个基类指针基类有虚析构函数和一个虚的调用函数当你把一个具体可调用对象赋值给 function 时模板构造函数会实例化一个派生类这个派生类保存目标对象并实现具体的调用逻辑。此后所有对这个 function 的调用都通过基类指针走一次虚函数分发实际执行的是模板派生类里对目标对象的调用。这里的第一次构造开销值得注意。目标对象会被复制或移动进派生类内部具体取决于你怎么赋值。如果你传的是一个很大的对象这里会发生拷贝如果只是函数指针或无捕获 lambda代价接近于零。这也是为什么有些代码在热路径上宁愿自己写模板也不想用 std::function 的原因——多一次间接调用对一些极高频场景是有影响的。2.2 function 内部的小对象优化与堆分配很多标准库实现会给 std::function 做SBOSmall Buffer Optimization也就是小对象优化。目标对象足够小时比如一个函数指针、无捕获 lambda、非常小的仿函数实现会直接把它放在 function 对象内部的缓冲区内完全避免堆分配。只有对象超过缓冲区大小时才会退回到堆上分配。这个设计对使用方式有明显影响。不同标准库实现的缓冲区大小不一样通常在 16 字节上下这意味着一部分有捕获的 lambda 或绑定了较多参数的 bind 表达式放入 function 时可能触堆分配。如果你有一个回调队列频繁往容器里 push 一堆 function最好优先考虑移动语义用std::move把临时 function 转移进去避免无谓拷贝。另一个实践技巧是尽量减小捕获列表的容量。捕获三个 int 的 lambda 和捕获两个 int 的 lambda在缓冲区边界上可能有本质差别。2.3 空状态、拷贝语义与不可拷贝对象默认构造的 std::function 是空的用operator bool()可以判断是否有目标。对空的 function 直接调用operator()会抛出std::bad_function_call异常。很多框架代码在调用回调前没做空判断一旦回调没被正确注册程序就会在运行时崩溃排查起来比较费劲。拷贝语义上std::function 要求目标对象可拷贝构造。这个限制在 C14 之后更容易撞上lambda 通过初始化捕获可以移动捕获一个std::unique_ptr但这样的 lambda 本身是不可拷贝的没法放进 std::function。一个常见的绕法是用std::shared_ptr把不可拷贝对象包起来再捕获或者自己写一个轻量的 function_ref 只保存引用、不拥有对象。注意std::function 内部保存的是目标对象的副本。如果外面那个对象在构造后又被修改了function 里的副本不会同步变化。想要同步行为就得在构造时传入引用包装器比如std::ref。这个细节经常被忽略。3. std::bind参数适配与重排的胶水3.1 占位符与参数重排原理std::bind 最核心的机制是占位符。std::placeholders::_1、_2、_3等分别代表调用时传入的第 1、第 2、第 3 个实参。bind 在构造时记录下原函数和整个参数列表调用时再把真实实参填充到占位符的位置最后调用原函数。看一个典型的参数重排例子#include functional using namespace std::placeholders; void report(int priority, const std::string msg, double timestamp) {} auto f std::bind(report, _2, _1, 3.14); f(disk usage high, 8); // 等价调用 report(8, disk usage high, 3.14)这里调用f(disk usage high, 8)时第一个实参disk usage high填入_1的位置也就是 report 的第二个参数第二个实参8填入_2的位置也就是 report 的第一个参数。占位符让函数参数可以任意重排这在接口适配时常有奇效。占位符本身是一种特殊的对象类型bind 在编译期和运行期都能识别它。注意std::bind 返回的函数对象在调用时允许传入多余的实参这些没有被任何占位符引用的实参会被丢弃。虽然这在语法上合法但我一般不推荐依赖这个特性代码可读性会下降容易让后来维护的人误解签名对应关系。3.2 值拷贝、std::ref 与生命周期std::bind 的一个反直觉之处在于绑定的参数默认按值拷贝。比如下面这个例子如果不小心忘了std::ref结果会和预期差很远void add_value(int total, int value) { total value; } int sum 0; auto inc std::bind(add_value, sum, _1); // 错误sum 被拷贝了 inc(5); // sum 仍然是 0因为 bind 内部持有的是 sum 的副本 auto ok std::bind(add_value, std::ref(sum), _1); // 正确引用绑定 ok(5); // sum 变成 5std::ref返回一个reference_wrapper对象它能在拷贝语义下保留引用行为。std::cref则用于绑定 const 引用。凡是希望 bind 表达式与外部变量共享状态都要用 ref 或 cref 包裹。生命周期是另一个大坑。如果绑定了引用或者裸指针必须确保被引用对象在 bind 表达式存在期间一直存活。绑一个局部变量的引用再把 bind 表达式存入某个回调队列函数退出后局部变量析构后续调用就是悬垂引用程序可能随机崩溃。相比之下绑定std::shared_ptr是安全得多因为 bind 内部会持有智能指针的副本延长目标对象的生命周期。struct Order { void ship(int quantity) {} }; auto sp std::make_sharedOrder(); auto shipFn std::bind(Order::ship, sp, _1); // 持有 shared_ptr 副本安全3.3 嵌套 bind 与成员函数适配bind 表达式可以出现在另一个 bind 表达式的参数列表里形成嵌套。外层 bind 在调用时会先对内层 bind 表达式求值再把求值结果作为实参传给原函数int add(int a, int b) { return a b; } int mul(int x, int y) { return x * y; } auto f std::bind(add, std::bind(mul, _1, _2), 10); f(2, 3); // 等价于 add(mul(2, 3), 10)结果是 16注意求值时机嵌套 bind 只有在真正调用时才会被求值不是构造时求值。如果不想让它被求值、而是作为普通对象原样传给函数可以用std::ref把内层 bind 对象包起来。这个机制理解后组合复杂表达式才不会出错。成员函数绑定是另一个高频用法。成员函数指针必须配合对象实例使用bind 可以把对象作为第一个参数一起绑进去class Channel { public: void send(const std::string msg, int priority) {} }; Channel ch; auto sendUrgent std::bind(Channel::send, ch, _1, 100); sendUrgent(alert); // 等价于 ch.send(alert, 100);这里绑定的ch是裸指针不会复制 Channel 对象。如果 Channel 是局部对象同样存在生命周期问题。把ch换成ch则会把整个 Channel 拷贝进 bind 表达式通常没人这么干。绑定智能指针则兼顾安全与便捷。4. function bind 联合作战的典型场景4.1 带参任务统一进任务队列任务队列几乎是我见过的最常见的 function bind 组合场景。队列只想接收void()形式的任务但业务函数可能有两个、三个甚至更多参数。用 bind 提前把参数扣住就能把各种签名统一成void()class TaskQueue { public: using Job std::functionvoid(); void submit(Job job) { queue_.push_back(std::move(job)); } void runAll() { for (auto job : queue_) job(); queue_.clear(); } private: std::vectorJob queue_; }; void generateReport(const std::string path, int level) {} TaskQueue tasks; tasks.submit(std::bind(generateReport, /tmp/rpt.txt, 2)); tasks.runAll();这里std::bind构造的表达式被隐式转换为std::functionvoid()实际调用时不再需要外部参数。关键点在参数拷贝绑定/tmp/rpt.txt时字符串字面量会被存成const char*调用 generateReport 时才转成 std::string这没问题但如果你绑定的是一个 std::string 局部变量bind 会拷贝一份字符串增加开销。如果文件很大可以考虑绑定智能指针或改用便于拷贝的轻量描述。4.2 接口签名不匹配时的适配业务里经常遇到接口签名和回调签名对不上的情况。比如某个事件处理器只关心事件中的部分字段bind 可以从容适配。假设事件分发器对外回调签名是void(int deviceId, int status)但某个处理函数只需要 deviceIdvoid onAlert(int deviceId) {} using StatusHandler std::functionvoid(int, int); StatusHandler handler std::bind(onAlert, _1); handler(17, 3); // 等价于 onAlert(17)第二个参数被丢弃反过来也可以提前固定参数。比如有一个日志函数void log(Level level, const std::string msg)想把它改造成一个只接收 msg 的回调void log(Level level, const std::string msg) {} std::functionvoid(const std::string) logger std::bind(log, Level::Warning, _1); logger(disk nearly full); // 等价于 log(Level::Warning, disk nearly full)这类适配在写 UI 回调、插件系统、测试替身时非常常见。bind 加上 function等于在类型系统层面完成了一组灵活的接口变换而不需要为每一种组合单独写一版适配类。4.3 放到算法与延迟执行里把 bind 用进标准库算法是另一个常被忽略的玩法。比如std::sort的比较器签名是bool(const T, const T)但你的比较函数可能已经把这两个参数定义为相反顺序struct Less { bool operator()(int a, int b) const { return a b; } }; std::vectorint values {3, 1, 4, 1, 5}; std::sort(values.begin(), values.end(), std::bind(Less{}, _2, _1)); // 降序排列注意这里Less{}被 bind 按值拷贝operator() 必须是 const 或可调用。如果是带状态的比较器拷贝状态也会发生使用时心里要有数。延迟执行场景更直接。std::async、线程池提交、超时任务表都可以用 bind 把参数打包进无参任务void heavyParse(const std::string raw, int mode) {} auto future std::async(std::launch::async, std::bind(heavyParse, input, 1));线程池完全可以用std::functionvoid()作为任务类型配合 bind 把任何业务函数变成可提交的任务单元。这套模式在服务器开发、桌面客户端后台任务、游戏引擎的帧任务表里都有广泛应用。5. 高频问题速查和性能观察5.1 编译错误对照速查表我整理了一些高频出现的编译错误和对应原因按症状速查比较方便编译错误或运行现象可能原因解决方式_1 was not declared in this scope没有引入占位符命名空间添加using namespace std::placeholders;no match for call to (std::functionvoid(int)) (int, int)调用 function 时实参数量或类型与签名不符核对签名必要时用 bind 丢弃多余参数运行时抛出std::bad_function_call对空 std::function 调用了 operator()调用前检查if (fn)或初始化默认回调目标不可拷贝导致构造失败lambda 捕获了不可拷贝对象用std::shared_ptr包一层或改存自定义 function_ref成员函数作为可调用对象时编译不过漏掉对象实例参数使用std::bind(Class::method, obj, _1)形式bind 绑定引用参数后外部变量无变化忘记用std::ref包裹引用参数改为std::bind(func, std::ref(var), _1)这些错误我基本都在项目里撞过。最隐蔽的是第一种之外的问题——编译能过、运行结果不对那多半是拷贝语义或生命周期出了岔子建议优先排查 bind 的参数是否用了 ref以及绑定对象的存活范围。5.2 性能开销与内联观察关于性能我做过几次简化实验结论比较稳定。开启 -O2 优化后对同一个函数直接调用、通过 lambda 调用、通过 bind 调用通常差异极小因为编译器往往能把调用链内联到只剩一条跳转甚至直接内联进去。std::function 则不一样它必须走类型擦除的间接路径大部分实现里无法完全内联而且目标较大时还伴随堆分配开销。我整理了一张定性对比表调用方式是否保留具体类型能否内联是否可能堆分配函数指针是有时取决于调用位置可见性否lambda是通常可以否bind 表达式是构造后仍是具体类型通常可以取决于绑定对象大小std::function否类型已擦除一般不行可能小对象优化可以避免这不是说 function 不能用于业务代码而是在百万次循环内的热路径或者几十微秒级延迟敏感的场景尽量减少 function 的参与。回调分发本身往往不是瓶颈但如果你在性能分析里看到std::_Function_handler的调用占用了不少 CPU 时间就要考虑把这段改成模板或直接函数指针。5.3 bind 和 lambda 怎么选C14 之后很多场景下 lambda 是比 bind 更直观的选项因为可读性更好、捕获语义明确、逻辑表达自由。但 bind 在一些特定场景依然有优势当你已经有一个具名函数只需要固定部分参数或重排顺序时bind 一行就能写完lambda 反而要写参数列表和函数体。我给一个选型参考场景推荐写法理由固定已有函数的若干参数std::bind(func, arg1, _1)简洁、声明式参数顺序需要重排std::bind(func, _2, _1)bind 天然支持需要多条语句和局部变量lambda可读性远好于 bind 嵌套需要捕获不可拷贝对象lambda shared_ptrbind 不解决移动捕获需要把回调存进容器std::function 包装二者之一类型擦除是最终目标我的个人习惯是默认写 lambda只在 bind 明显更短、更声明式时才用 bind。一个简单的判断标准是如果一行 bind 表达式能清楚表达意图就不要换成十几行的 lambda如果 bind 表达式需要嵌套两三层才能读明白就直接上 lambda。特别注意std::bind 在面对重载函数时比较麻烦因为编译器不知道你要绑的是哪个重载版本。可以先对目标函数做static_cast指定版本或者用 lambda 包一层让重载决议在 lambda 内部发生。后者我实践下来更省心。最后说一点个人体会我用 function 和 bind 的时间越长越觉得它们不是同一层面的东西function 是容器bind 是胶水。function 解决的是类型统一与存储问题bind 解决的是参数形态变换问题两者组合起来几乎可以覆盖所有回调分发需求。但代码不只是给编译器看的更是给下一个维护者看的。我在实际项目里的经验是如果 bind 的嵌套或占位符重排让同事多看了十秒才反应过来那就果断换成 lambda可读性永远是第一位的。反过来如果只是一个简单的前缀绑定或参数重排bind 的声明式写法确实比 lambda 更干净。工具没有对错只有在这个上下文里合不合适。希望这篇文章能把这两个工具的边界和默契讲清楚让你在下次设计回调接口时少走几个弯路。

相关新闻

硕词 AI 任务书写作 —— 规范论文开题第一步

硕词 AI 任务书写作 —— 规范论文开题第一步

论文任务书是写作的起点,但很多学生不知道如何撰写。硕词 AI 提供任务书智能写作,登录 www.shuociai.com,快速生成规范、符合学校要求的论文任务书。 内容包括研究题目、研究内容、研究目标、进度安排、参考文献等,结构完整、表达…

2026/10/10 4:37:17 阅读更多 →
GRPO参考实现全解析:从PPO到组相对策略优化的工程实践

GRPO参考实现全解析:从PPO到组相对策略优化的工程实践

1. GRPO到底是什么,为什么最近大家都在聊GRPO,全称Group Relative Policy Optimization,组相对策略优化,是最近强化学习训练大模型这条赛道里热度蹿升最快的一个算法。如果你关注过DeepSeekMath、DeepSeek-R1,或者Kimi…

2026/10/10 4:36:17 阅读更多 →
RIPS静态分析原理与PHP代码安全审计实战指南

RIPS静态分析原理与PHP代码安全审计实战指南

1. 项目概述:这不是“扫漏洞”的工具,而是代码安全的显微镜“基于RIPS的代码安全审计”——这八个字背后,藏着很多开发者第一次接触时容易误解的点。我带过不少刚从学校出来的实习生,他们一听到“RIPS”,第一反应是“哦…

2026/10/10 4:36:17 阅读更多 →

最新新闻

GoGoCode 基础教程:用代码选择器驱动 AST 级代码转换

GoGoCode 基础教程:用代码选择器驱动 AST 级代码转换

开发工具 【免费下载链接】gogocode GoGoCode is a transformer for JavaScript/Typescript/HTML based on AST but providing a more intuitive API. 项目地址: https://gitcode.com/gh_mirrors/go/gogocode 点击查看 免费下载 GoGoCode 是一款面向 JavaScript/Ty…

2026/10/10 5:59:46 阅读更多 →
Maddy 出站投递安全机制全解析:MX 认证与 TLS 强制(MTA-STS / DNSSEC / DANE)

Maddy 出站投递安全机制全解析:MX 认证与 TLS 强制(MTA-STS / DNSSEC / DANE)

后端通信 【免费下载链接】maddy ✉️ Composable all-in-one mail server. 项目地址: https://gitcode.com/gh_mirrors/ma/maddy 点击查看 免费下载 本文是 maddy 邮件服务器出站投递安全体系的技术指南,围绕 docs/seclevels.md 展开,系统讲…

2026/10/10 5:59:46 阅读更多 →
桌面与手机美化怎么做,多款 AI 壁纸生成工具使用记录

桌面与手机美化怎么做,多款 AI 壁纸生成工具使用记录

日常手机、电脑桌面美化,自媒体配图、背景素材制作时,经常需要适配不同设备尺寸的壁纸图片。不同 AI 壁纸工具,在尺寸适配、画面风格、高清放大、批量产出、画面细节把控上存在明显区别。下文客观记录五款壁纸相关工具的基础能力与使用局限&a…

2026/10/10 5:59:46 阅读更多 →
前端面试算法与数据结构备考指南:以树的遍历为核心的 JavaScript 编码实战(front-end-interview-handbook)

前端面试算法与数据结构备考指南:以树的遍历为核心的 JavaScript 编码实战(front-end-interview-handbook)

前端文档教程 【免费下载链接】front-end-interview-handbook Front End interview preparation materials for busy engineers (updated for 2026) 项目地址: https://gitcode.com/GitHub_Trending/fr/front-end-interview-handbook 点击查看 免费下载 本指南以 f…

2026/10/10 5:59:46 阅读更多 →
Skills 技能库 container-lines 实战:用 1px 容器参考线与迷你角标构建精确、克制的 Web 布局

Skills 技能库 container-lines 实战:用 1px 容器参考线与迷你角标构建精确、克制的 Web 布局

【免费下载链接】Skills Agent skills for designers and builders using Codex, Claude, Cursor, and other AI coding agents 项目地址: https://gitcode.com/gh_mirrors/skills48/Skills 点击查看 免费下载 本指南基于 GitHub 加速计划 skills48/Skills 仓库中的…

2026/10/10 5:59:46 阅读更多 →
回溯算法综合练兵:组合总和、优美排列与状态机详解

回溯算法综合练兵:组合总和、优美排列与状态机详解

很多人学完递归就卡在回溯,原因只有一个:递归只需要一路向前,回溯还要学会高明的“后悔”。本次专题(五)正好到了综合练兵的中段,我用三个经典的搜索问题——组合总和、优美排列、状态机——把回溯的剪枝、…

2026/10/10 5:58:45 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →