C++默认参数避坑指南:从接口设计到底层机制全解析

1. 默认参数解决的,其实是接口设计问题

几个月前我帮忙维护组里的一个内部日志模块,看到调用方代码时人有点懵。模块对外暴露了七八个接口,每个接口都有三四个参数,其中大半是调用方根本不关心的内部配置。更别扭的是,业务方想打印一条消息,也得把那几个跟日志轮转、文件编码相关的参数全部填一遍。实际效果就是大量调用长得高度相似,只有消息文本不一样,其余全是同一套“默认配置”。

后来我做的第一件事,就是给这些函数加上默认参数,把那些“大多数时候不需要改”的参数从调用方的心智负担里删掉。调用方果然清爽了很多,该填哪个填哪个,不想填的省了。这个过程让我对默认参数的价值有了直观认识:它表面上是“省几个字”的语法糖,本质上是在重新设计一个 API 的可用性边界。

C++ 的默认参数(default argument)允许我们在声明函数时为部分形参预设初值。调用时若省略这些参数,编译器会自动用预设值补齐。听起来简单,但展开后会发现里面牵扯到声明与定义的关系、参数求值时机、虚函数分发、模板推导、函数指针类型等一系列在短代码里看不见的暗礁。

这篇文章适合三类读者:一是刚开始写 C++,正在为函数接口怎么设计而纠结的新手;二是维护老项目、经常被历史代码坑到的同学;三是做库和 SDK、需要认真设计对外 API 的人。我会从基本用法讲起,再深入拆解规则背后的编译机制,最后把那些实战中翻车率最高的场景逐一展开。很多问题你在网上能查到“这么写会报错”,但很少有人解释到底为什么。这篇文章我尽量把机制讲透。

2. 绕不开的几条基本规则:位置、声明、求值时机

2.1 位置铁律:默认参数只能从右往左连续排列

先看一段典型代码:

void connect(const std::string& host, int port = 8080, int timeout = 3000); connect("localhost"); // 三个参数全用默认 connect("localhost", 5000); // port 覆盖,timeout 用默认 connect("localhost", 0, 1000); // 两个都覆盖

这里没问题,因为port和timeout的默认值从参数列表最右侧开始,连续排列。但下面这种写法在 C++ 里是编译错误:

void badConnect(const std::string& host = "127.0.0.1", int port);

为什么会这样?原因在于函数调用是严格按位置匹配实参和形参的。你写badConnect("some_host", 80)时,编译器可以匹配;但你写badConnect()时,它怎么知道port应该是多少?默认参数从右边开始连续排列,编译器才可能做到:省略的一定是最靠右的那些参数,位置关系一目了然。如果允许在中间留空档,函数调用时省略参数的规则就会变得混乱。

2.2 默认参数只能声明一次:头文件声明与定义二选一

默认参数不能在同一作用域内被重复指定。最常见的正确做法是:默认参数只写在头文件里的函数声明处,源文件里的函数定义不再写默认值:

// log.h void writeLog(const std::string& msg, int level = 0, bool flush = true); // log.cpp void writeLog(const std::string& msg, int level, bool flush) { // 这里不重复写默认参数 }

如果你在声明里写了默认值,在定义里又写了一遍,大多数编译器会直接报“默认参数重定义”之类的错误。就算你只在声明写一遍、定义写一遍,只要两个翻译单元里对同一函数的声明之一带了默认参数而另一个没带,也会很快踩到“默认参数不一致”的坑。

那条实际经验我放在后面讲避坑时详细说。这里先记住结论:默认参数默认放在给外部可见的第一个声明里,通常是头文件。定义处保持干干净净,反而最容易维护。

2.3 默认值在调用点求值,不在编译期“烧录”

很多人对默认参数有一个错误理解:以为默认值是编译时写死的常量,调用时直接替换。其实不是。

默认参数本质上是一个表达式,它的求值发生在函数调用点,而且是在调用者上下文里发生的。看这个例子:

int g_timeout = 3000; void request(int timeout = g_timeout); void toggleTimeout() { g_timeout = 5000; request(); // 实际拿到的是 5000,不是声明时的 3000 }

request()没有传参时,表达式g_timeout在调用点被求值,所以拿到的是当时的全局变量值。这带来两个推论:

  • 默认参数可以是全局变量、函数调用、表达式,甚至是对象构造表达式。
  • 每次省参数调用时,默认表达式都会重新求值一次,不是缓存一次结果一直复用。

正是因为这个特性,默认参数的入参不应该写成有副作用的表达式,也不应该依赖某个变量“此刻应该是什么值”。临时的状态会让函数行为变得很难预测。最稳妥的默认值还是字面量、枚举值、常量表达式,至多是一个全局常量对象。

2.4 默认参数不属于函数签名,但会影响可调用形态

函数签名在 C++ 里由函数名、参数类型、限定符等决定,默认参数本身并不参与签名判断。这意味着两个声明:

void process(int value, bool verbose = false); void process(int value, bool verbose);

其实是同一个函数,不是重载。也正因如此,默认参数不能改变函数指针的类型,这点很多人一开始会忽略。

可一旦默认参数出现在声明里,这个函数在重载决议时又表现出一些“额外的形状”:比如process(1)被允许,而没写默认参数时process(1)根本不会落入候选。这种“签名上不算数,可用时又算数”的双重身份,正是后续很多坑的根源。

3. 六个高频翻车现场:现象、原因、排查链路

3.1 虚函数与默认参数的“静态绑定”陷阱

这是默认参数在面向对象场景里最经典的一个坑。看这段代码:

struct Base { virtual void speak(int volume = 10) { std::cout << "Base: " << volume << std::endl; } }; struct Derived : Base { void speak(int volume = 99) override { std::cout << "Derived: " << volume << std::endl; } }; Derived d; Base& b = d; d.speak(); // 输出 Derived: 99 b.speak(); // 输出 Derived: 10

同一个对象,通过不同静态类型的引用调用,默认参数一个取 99,一个取 10。很多初次遇到的人会直接懵掉:b明明指向的是Derived,虚函数也正确分发到了Derived::speak,可默认参数为什么是基类版本的 10?

原因在于 C++ 对默认参数的解析发生在编译期,编译器根据调用表达式的静态类型去取默认参数。而虚函数的分发发生在运行期,根据对象的动态类型决定调用哪个版本。默认参数和虚函数分别被“静态解析”和“动态分发”,两边不会打通。也就是说,编译器在编译b.speak()时,看到b的静态类型是Base&,于是拿Base::speak的默认参数 10;运行到那一刻,虚函数机制又把实现换成了Derived::speak,但参数已经被填成 10 了。

我当时用调试器排查这个现象时,一度以为是派生类覆盖没生效,后来才发现是入参本身就不对。这个案例也说明一个设计原则:派生类覆盖虚函数时,默认参数值一定要和基类保持一致,或者干脆不要依赖默认参数来做差异化逻辑。如果确实需要不同的默认行为,更好的做法是拆成两个虚函数接口,让带参数的版本明确传参。

3.2 函数指针、std::function 会悄悄丢掉默认参数

默认参数只在“调用表达式直接基于函数声明”时生效。一旦函数地址被转成函数指针,或者包装进std::function,默认参数就完全失效。这里有一个很常见的编译错误场景:

void logMessage(const std::string& msg, int level = 0); void (*funcPtr)(const std::string&, int) = &logMessage; // 类型吻合 std::function<void(const std::string&)> cb = logMessage; // 报错:签名不匹配

为什么std::function<void(const std::string&)>接收不了logMessage?因为函数指针的类型里包含完整参数列表,logMessage的类型是void(*)(const std::string&, int),默认参数不会让它的类型变成“少一个参数”。也就是说,C++ 并不存在“带默认参数的函数自动降维成少参数函数指针”的规则。

我在一个事件回调系统里踩过类似问题。当时想省事,把一个带默认参数的日志函数直接塞进事件回调,结果编译期报了一堆类型不匹配。替代方案也很简单:用 lambda 包一层,把默认值放进 lambda 体内:

std::function<void(const std::string&)> cb = [](const std::string& msg) { logMessage(msg); };

这其实是默认参数在“可调用对象”场景下的一个通用教训:默认参数不被其他类型的可调用对象继承。回调里想保留默认行为,就让包装层自己决定参数值。

3.3 默认参数与重载叠加后的二义性

默认参数和函数重载叠加,如果不小心,很容易构造出重载决议的沼泽。看这段代码:

void draw(int x, int y = 10); void draw(int x); draw(1, 20); // 没问题,匹配第一个 draw(1); // 编译错误:二义性

为什么draw(1)报二义性?因为第一个函数在省略第二个参数后,可以用一个实参完成一次正常调用;第二个函数本身就是一个参数的版本。于是两个候选函数对draw(1)的可匹配程度完全一样,没有哪一个更优,编译器只能判定二义。

这个问题在重构代码时尤其容易踩。比如原来只有一个两参数版本,后来想加一个单参数语义的重载,结果一加就破坏了原来的调用。遇到这种场景,我一般会停下来想一下:新的“单参数语义”跟旧函数省略默认参数之后的语义是否重叠?如果重叠,就不应该用重载,直接靠默认参数也许就够了;如果语义确实不同,那就把参数类型区分开,而不是让两个重载产生相同的调用入口。

3.4 默认参数里的临时对象与引用生命周期隐患

默认参数可以是表达式,那自然可以返回对象。这引出生命周期问题。最常见的隐患长这样:

std::string getDefaultName() { return std::string("tmp"); } void printName(const std::string& name = getDefaultName());

表面看没问题:getDefaultName()返回临时std::string,临时对象绑定到const std::string&,生命周期足够覆盖整个函数调用。C++ 标准保证这种满表达式求值结束前,临时对象不会析构,所以这里其实是安全的。

真正危险的是默认参数表达式返回引用或指针的场景。看这个:

int& getLocalValue() { int local = 3; return local; // 悬垂引用 } void setPriority(int& value = getLocalValue()); // 编译期可能不报错

getLocalValue()返回一个指向已销毁局部变量的引用,默认参数把这个悬垂引用传进函数,函数内部用到时读到的都是未知数据。这类代码在编译期没有任何提醒,运行期可能时好时坏,是最难排查的一类问题。建议是:默认参数表达式的返回形态,尽量是值语义或 const 全局对象,不要返回对局部对象、成员临时对象或手动管理内存的裸指针。

还有一类稍隐蔽的副作用问题:默认参数表达式可能分配资源。比如:

std::unique_ptr<int> makePtr() { return std::make_unique<int>(5); } void consume(const std::unique_ptr<int>& p = makePtr());

如果consume每次省略参数,都会重新构造一个unique_ptr,而如果函数内部只是借用指针而不转移所有权,这种写法会每调用一次就分配释放一次,性能比显式传一个共享对象差很多。默认参数的真正语义是“省略”,它不该变成一个隐藏在调用里的资源工厂。

3.5 构造函数默认参数与对象创建的暗坑

构造函数同样可以使用默认参数,而且非常常见:

class Widget { public: Widget(int w = 100, int h = 50); }; Widget w1; // 正确,使用默认参数 Widget w2{}; // 正确,C++11 及以后推荐 Widget w3(); // 陷阱:这不是对象定义,而是函数声明

Widget w3();是 C++ 里著名的“最令人困扰的解析”。当一个默认参数版构造函数可以无参调用时,你看到Widget w3();的第一反应是定义了一个对象,但编译器把它解析成一个返回Widget、无参函数名叫w3的函数声明。这种问题在默认构造函数里更容易出现,因为新手往往以为带默认参数的构造函数配合()是合法的对象初始化。

再有一个隐患是构造函数默认参数导致的隐式转换。一个带默认参数的构造函数,如果第一个参数类型是非explicit的,那它可能意外地成为从该类型到类的隐式转换路径:

class Metric { public: Metric(double value = 0.0, const std::string& tag = "default"); }; void report(Metric m); report(3.14); // 编译器自动构造 Metric,可能不是你的本意

多参数构造函数如果不加explicit,只要剩下的参数都有默认值,它就能被单参数触发隐式转换。如果你不希望发生这种隐式构造,记得加上explicit。这一点在新手构造函数设计里经常被忽略,但它直接影响代码的可读性和后续维护所需的警惕程度。

3.6 模板场景:默认模板参数与函数默认参数是两回事

涉及模板时,默认参数的话题会再复杂一分。先区分两个概念:

template <typename T = int> void pureTemplate(T value) { } template <typename T> void withDefault(T value = T{}) { } pureTemplate(); // 正确:T 用 int,可以不传参 withDefault(); // 编译错误:T 无法从默认参数推导出来

第二个函数报错,关键点在于:函数模板的模板形参T不能仅靠“函数默认参数”来推导。编译器在推演函数实参类型时,看到的调用是零实参,它不知道T应该是什么,T{}虽然可以给实参一个默认值,但模板实参推导并不把默认函数参数作为推导来源。

这种问题在泛型代码里很容易被误用。我见过有人写一个事件分发模板,想着“缺省就默认模板参数”,结果编译不过。正确写法是把默认模板参数和函数默认参数配合起来:

template <typename T = int> void withBoth(T value = T{}) { } withBoth(); // 正确:T = int,value 初始化为 0

这个例子同时展示了两个默认机制如何协作:模板默认参数负责解决“T 是什么”,函数默认参数负责解决“value 未提供时填什么”。

4. 工程选型:默认参数、函数重载还是包装函数

写代码时经常会面临一个抉择:一个函数在不同场景下有不同数量的参数需求,到底用默认参数、重载,还是再包一层?

默认参数适合的场景是:函数实现只有一个版本,多个参数只是同一操作的不同调节项,省略参数后走的就是最常见的默认行为。比如网络连接里的 port 和 timeout,打印日志里的 level 和 flush,这些用一个函数加默认参数,语义最清晰。因为它本质上是在说“这些参数可省略”。

函数重载适合的场景是:几个不同入参组合对应着不同的实现路径或不同的语义。比如一个render函数,接收图像对象和接收文件路径,这是两种处理,用重载分开更合理。又比如某参数存在与否会改变函数整体行为(记录日志 vs 不记录),这时重载的显式签名本身就是一种文档。

还有一个折中方案是包装函数:

void process(const std::string& data, bool verbose, int retry); void processNoRetry(const std::string& data) { process(data, false, 0); }

包装函数在工程上非常常见,它的好处是:每个包装函数都有明确的名字,语义表达更强;而且包装层强制调用方“做出选择”,不会出现忘记参数导致的隐式默认行为。缺点是代码量稍微多一点。

我个人的选择逻辑是这样:如果只是“少数几个调节项偶尔需要改”,用默认参数;如果是否存在某行为是本质区别,用重载或不同的函数名;如果调用方语义需要非常明确、不希望有“省略即默认”的隐式理解,那就直接包一层并起一个不含糊的名字。三者可以组合,但组合时特别小心重载函数与默认参数的二义性——前文已经踩过那个坑了。

5. 我在实际项目里的几条默认参数守则

文章最后,分享几条我自己在项目里总结的实践守则。这些不是 C++ 标准要求,却是我踩过几次坑之后沉淀下来的约束。

第一,默认参数只写在声明里,定义绝不重复。统一放在头文件第一个声明处,那个位置就是所有调用方看到的“API 文档”。定义处重复写默认参数,不仅容易触发编译错误,还会随着代码演进产生两个不一致的“事实来源”。

第二,默认参数值尽量是编译期可见的简单表达式。字面量、枚举值、静态常量表达式都行。避开全局变量、成员函数调用、资源分配表达式。这样可以保证调用行为可预期,也避免开头讲的“默认值在调用点求值”带来的不确定性。

第三,派生类覆盖虚函数时,如果基类带默认参数,派生类要么保持一致,要么干脆不写默认参数。任何意义上的默认值分歧,从调用结果来看都是一颗定时炸弹。因为代码里传引用和指针的地方太多了,你根本控制不了调用者拿到的静态类型。

第四,需要回调或函数指针时,用 lambda 包一层默认参数,而不是期待默认参数自己穿透可调用对象层。这是从函数指针和std::function的坑里总结出来的:可调用对象的签名是严格的,默认值不会替你做任何事。

第五,默认参数不是万能的,别把复杂的显式调用语义藏进“省几个字”里。某些情况下,宁可多写一个包装函数,让调用方的意图直接体现在函数名里。一个小技巧:代码评审时如果看到“调用处省略参数但含义不明显”的代码,我会建议把它改成显式传参。这听上去有点反直觉,但真的能减少很多“读代码猜意图”的时间。

默认参数是一个很小的语言特性,但它的设计取舍和隐藏行为,能直接反映一个人对 C++ 这门语言底层机制的熟悉程度。把这篇文章涉及到的规则和场景消化掉,你在设计接口时就会多一层判断力,也少走一段只属于 C++ 的弯路。

相关新闻

气动力辨识的Observer法:从EKF状态空间建模到工程避坑

气动力辨识的Observer法:从EKF状态空间建模到工程避坑

简介&#xff1a;基于Observer&#xff08;状态观测器&#xff09;法实现的气动力辨识程序&#xff0c;聚焦航空航天与飞行控制领域&#xff0c;面向需要从飞行器动态行为中估计升力、阻力、侧向力等难以直接测量参数的研究者或工程师&#xff0c;解决气动模型建立与参数辨识难…

2026/10/20 23:34:16 阅读更多 →
Spring Boot+元宇宙的房屋租赁管理系统毕业设计完整解析

Spring Boot+元宇宙的房屋租赁管理系统毕业设计完整解析

又是一个毕业设计选题问题。每年到这个节点&#xff0c;总有同学拿着"XX管理系统"的题目来找我聊&#xff0c;但今年这个标题明显有点不一样——"基于Spring Boot的元宇宙平台的房屋租赁管理系统"。说实在的&#xff0c;第一次看到这个题目我愣了一下&…

2026/10/20 23:34:16 阅读更多 →
Hive 3.1.2 UDF开发避坑指南:从环境配置到GenericUDF实践

Hive 3.1.2 UDF开发避坑指南:从环境配置到GenericUDF实践

Hive 3.1.2 版本做 UDF 开发&#xff0c;是个挺容易踩坑的活儿。网上很多教程还停留在 Hive 1.x/2.x 的老写法&#xff0c;照着做大概率会碰到类冲突、方法签名不识别这类问题。我自己在 3.1.2 上踩了一轮坑之后&#xff0c;把完整流程和避坑点整理出来&#xff0c;希望能帮你少…

2026/10/20 23:34:16 阅读更多 →

最新新闻

ADC采样精度与取平均实战:从原理到配置的避坑指南

ADC采样精度与取平均实战:从原理到配置的避坑指南

ADC 这个模块&#xff0c;说起来简单&#xff0c;做起来坑多。很多人第一次接触模数转换&#xff0c;觉得不就是把模拟电压读进来变成数字嘛&#xff0c;配置一下寄存器、开个通道、读个值就完事了。但真正到了项目里&#xff0c;你会发现读回来的数跳得厉害、精度对不上、采样…

2026/10/21 0:09:19 阅读更多 →
低压变频器EMC整改:时频特性驱动的接地与滤波工程实践

低压变频器EMC整改:时频特性驱动的接地与滤波工程实践

1. 为什么低压变频器总在调试现场“闹脾气”——从一台停机的输送带说起某自动化集成项目现场&#xff0c;三台7.5kW低压变频器驱动的辊道输送带&#xff0c;在空载运行时一切正常&#xff1b;一旦接入PLC的4–20mA模拟量给定信号并启动负载&#xff0c;系统就频繁报“通讯超时…

2026/10/21 0:09:19 阅读更多 →
STM32C5与CubeMX2实战评测:新芯片定位与工具链重构体验

STM32C5与CubeMX2实战评测:新芯片定位与工具链重构体验

1. 从一块新板子说起&#xff1a;为什么我会关注 STM32C5 和 CubeMX2前段时间拿到一块搭载 STM32C5 系列芯片的测试板&#xff0c;第一反应其实不是兴奋&#xff0c;而是有点犹豫——要不要花时间折腾它。原因很简单&#xff0c;STM32 的生态已经非常成熟&#xff0c;F1、F4、H…

2026/10/21 0:09:19 阅读更多 →
基于STM32的智能体重秤设计:从传感器到蓝牙通信的完整实现

基于STM32的智能体重秤设计:从传感器到蓝牙通信的完整实现

1. 从一个厨房角落里的需求说起前阵子帮朋友改造他家的旧体重秤&#xff0c;拆开一看&#xff0c;里面就是一块廉价的8位单片机加一个称重传感器&#xff0c;显示用的是段码屏&#xff0c;功能单一到只能站上去看个体重数字。朋友抱怨说&#xff0c;家里老人眼神不好&#xff0…

2026/10/21 0:09:19 阅读更多 →
汽车电子宽温磁环电感可靠性验证实战指南

汽车电子宽温磁环电感可靠性验证实战指南

1. 为什么宽温磁环电感的可靠性验证&#xff0c;是汽车电子EMC测试前最易被忽视的“地雷”你手头正赶着一个车载ADAS控制器的EMC摸底测试&#xff0c;样机在常温下辐射发射&#xff08;RE&#xff09;和传导发射&#xff08;CE&#xff09;数据都压得不错&#xff0c;离Class 5…

2026/10/21 0:09:19 阅读更多 →
BiLSTM-CRF命名实体识别:可解释、轻量、高确定性的NER基线实现

BiLSTM-CRF命名实体识别:可解释、轻量、高确定性的NER基线实现

简介&#xff1a;本资源是一套面向NLP初学者与医疗领域AI开发者的命名实体识别&#xff08;NER&#xff09;实战项目&#xff0c;聚焦BiLSTM-CRF模型在临床文本中的实体抽取任务&#xff0c;解决病症、药物、操作等关键信息自动识别难题。资源共24个文件&#xff0c;涵盖5个核心…

2026/10/21 0:08:18 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

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