Rust 自 1.86 起有了稳定的 Trait 上溯转换 功能。例如 trait Base: Any{}
+ trait Derived: Base{}
,以前具体类型 &T
转为 &dyn Derived
后无法转为 &dyn Base
(只能通过 &T
直接转换到 &dyn Base
)。现在有了向上转换的支持,&T
可以转为 &dyn Derived
再转为 &dyn Base
,还能再转到 &dyn Any
然后通过 RTTI 向下转换回 &T
,完整的多态功能就此实现!!
Rust 项目的编译速度一直是个问题,它的根本原因并不是编译期检查、过程宏修改程序之类的,而是 Rust 将整个 crate
作为单个翻译单元。C++ 中每个 .cpp
文件都是独立的翻译单元、可以轻松并行编译,而 Rust 却不行(虽然文档说单个 crate
也能并行编译,但实际效果不佳)。这就要求了Rust 的大型项目必须将内容模块化以保持较快的编译速度。
一个 JavaScript 运行时大致可以分为两部分:底层 JS 引擎和语言层(提供异步、I/O 以及系统调用等支持)。目前最常用的三个 JS 运行时是 Node.js
、Deno
和 Bun
,它们底层的 JS 引擎分别选用 V8 或 JSCore ,更有趣的差异则是实现语言层的选择:Node.js
使用 C++
、Deno
使用Rust
、Bun
使用Zig
,这恰好体现了现代社区在编写高性能需求程序时的语言偏好。
某些营销号喜欢拿 C++23 的 std::print
说什么“划时代的版本”,还有一些人在各种特性下面评论“这不是 Py 的语法吗”,迷枵要在此反驳:
Bevy 的 Examples 是乱序的,而且官网的示例不全,需要去 Github 仓库看完整内容。这给迷枵带来了很大的困扰,有可能你刚刚还在看九切片图像,现在就变成了自定义 2D 渲染管线,下一节却是简单地绘制一个矩形。迷枵正尝试整理这些 Examples 并生成一个依赖图,然后可以用拓扑排序规划学习路线。
-
迷枵 博主 : 350 个样例,诶,大概需要两周时间?
Windows 文件资源管理器上方的地址栏是可以输入命令的,比如使用 cmd
可以在当前路径直接打开命令提示符,用 wt -d .
在当前路径打开 Windows Terminal,用 code .
在当前路径打开 vscode ( 可能需要环境变量)。
显然 Rust 没有继承,但是 UI 系统确实需要“继承”的设计模式,于是 Bevy 用宏为UI 系统实现了某种特殊的“继承”: Required Components #14791 ,这实在是泰裤辣。
这里的重点是一个本身没有反射的语言,ECS 系统如何获取自定义函数形参列表,并自动注入实参。事实证明 Rust 的泛型完全可以写的和 C++ 的某些模板一样复杂。
某些应用在后台也会劫持输入,比如网易云音乐默认后台也会监听快捷键,而这些快捷键被后台应用捕获后大概率就不会被前台应用捕获了。比如后台开着网易云,前台 vscode 中可能无法使用 ctrl+alt+up/down
插入多行光标。
C++23 起,可以将自身作为成员函数的首个参数,并通过此参数的类型实现 CV、引用 重载:
这并没有额外开销,且许多现代语言也使用这种表示方式。现在 CRTP(奇异递归模板模式)就能这样写:
旧式的 Base<Derived>
会生成多个 Base
类;而新方式则是一个 Base
类、单例化多个 name
函数。
C++ const_cast
只是“假装”移除了 CV 限定符,如果原指针/引用含 CV 限定符,则移除限定符后修改原数据是未定义行为。它的真正作用在于,某些函数或模板形参的指针/引用缺少 CV 限定符,但函数体或后续语句保证不会修改数据,此时可以通过强转传入 const
数据而无需拷贝一份可变数据。
编程社区的一种说法是:“Rust 对标 C++,Zig 对标 C。” 它们并不完美(比如 Zig 的功能足够强大、但学习成本也更高,Rust 的设计模式在曾经 OOP 的应用中如何使用 ),但的确是极其优秀的语言。
Zig 如何能实现超越 C 的性能,Rust 如何通过静态检查基本实现内存安全,现代语言在编译期能做多少事,新一代的错误处理模式的优势······作为 C/C++ 程序员,即使你暂时用不到这些语言,迷枵也建议你了解一下这些内容。
考试结束后的十几分钟或许是人最聪明的时候。。。
很多现代语言使用 LLVM 作为编译后端,自己仅实现编译前端从而避免处理的平台特定指令集。Zig 是一门现代编程语言,同时还是一个构建工具与编译器,其作者似乎正在亲自实现一个跨平台的编译后端(以代替LLVM)。用 Zig c++代替 CMake 和 MSVC/Clang/GCC 从而统一 C++ 开发环境,我怎么会做这种梦。
cppreference 的维护时长很快就到半年了,C++ 没有 cppref 就像······
C++ string/vector/map
等容器的增减元素和拷贝等操作都没有 noexcept
保证,但我们几乎从不处理它可能抛出的异常!!这类错误的发生应该直接让程序 “panic” 而非抛出异常,因此迷枵建议你将这些函数视为“安全”的,从而可为上层函数添加 noexcept
以优化性能和语义。
传统 Android 开发使用 XML 布局,类似 Web 的 HTML 和 QT 的 QML ,使用标记语言绘制 UI 的确是非常棒的选择。而现在的 Android 开发推荐使用 声明式 Kotlin API ,由于 Kotlin 优秀的语法,能够在 Kt 代码中使用形似标记语言的写法描述布局与组件,且比 XML 更加美观。
Zig 0.15 又改变了许多 API,比如输入输出系统,连 0.14 的 Hello World 程序都不兼容了。
Markdown 实际支持 HTML 标签,vscode 的预览对它的支持就很好。但是 Github 的 Markdown 渲染对 HTML 标签的支持极其有限,稍微复杂一点的属性就无法使用,比如你无法使用流式布局。
C++模块文件需要通过 `CXX_MODULES` 文件集加入项目,但此文件集类型不支持 INTERFACE,这意味着模块需要在自身的项目中编译。而启用模块又要指定 C++ 标准,这意味着一旦模块库本身和使用方的 C++ 标准不同(比如模块库设定了20,使用方却是 23)就会发生重定义问题。而目前的各种解决方案都很丑陋。
Rust 的 String
和 str
与其他语言不同,并非简单的字节数组。虽然内部实际使用 u8
存储,但它要求这些字节必须能够组成合法的UTF 字符。而像 C++ 的 std::string
则是非常纯粹的 char
数组,有些人甚至会用它存放二进制数据,这是非常不应该的(string
应存放可视化文本数据,而二进制数据应该使用 std::vector<char>
或 std::array<char>
)。
某些人会用“Rust 写个链表试试?”表示 Rust 的严格检查导致代码过于复杂,但实际上 Rust 写链表和 C++ 使用 unique_ptr
代替裸指针写链表并没有什么区别,非常简单(根本用不到 unsafe)。
在 Markdown 中,图片使用 
语法,此时的图片是可点击的(自动跳转到对应链接)。但是对于某些小标签(比如 README 中的一些 Tag),不希望点击跳转,此时可以在外面再包一层无效链接:[](#)
。这样的图片点击后会保持本网页不变。
某些语言的整数字面量以 0
(数字零)开头则会以八进制解析,没错说的就是 … 而某些聪明的语言直接取消了八进制,或者 0o
前缀才会启用八进制、就像十六进制的 0x
前缀,没错说的就是…
Windows的QQ,(更新后)侧边栏中的 “游戏” 终于可以隐藏了。
C++26 的编译期反射生成函数是基于模板的,因此生成全局函数很容易(只需要一个函数模板),生成类成员函数却比较麻烦(每个类都需要自动的成员函数模板,估计还需要通过宏简化代码)。Rust 的宏能 直接修改抽象语法树(类似 Clang API,但更简单),生成代码就方便的多。。
星穹铁道角色完全虚化时,影子也会消失哦。(另外,影子边缘平滑似乎是固定的?)
这是迷枵写的 JSON 库的性能测试结果:[mysvac-jsonlib – test] 。效果符合预期,整体略优于 nlohmann-json ,但还没达到 rapidjson 和 boostjson 等第一梯队的水平。若有兴趣可以尝试使用,虽然功能已经完善且通过诸多测试、但还不推荐应用在实际项目中。迷枵将在 C++26 静态反射支持后重构一遍 API ,实现最终版本。
空的 std::string
在 MSVC 中占 32B
,但是在 Clang/GNU
中是 24B
。
C++17 提供了 std::to_chars
和 std::from_chars
函数用于快速处理浮点数和字符串之间的转换。to_chars
直接将数据写入指针,无需生成 std::string
,处理速度比 std::format
或者 printf
快好几倍。from_chars
同样显著优于 stox
系列函数。
迷枵之前的 C++17 mysvac-jsonlib 选择字符串存储数据,因此序列化与反序列化速度甚至能超过 rapidjson 等最快的库(稍作优化后),但代价是访问与修改数据时需要进行类型转换与文本转义。迷枵在 C++20 版本又将其改回了普通模式。
《剑来》竟然一周更了两章。
总所周知现代 C++ 推荐使用 { }
初始化,这通常没有问题,可以调用任意构造函数。但在类型支持初始化列表构造时就很容易出错,若再加上隐式转换就会出现非常复杂的问题。
vscode 的 copilot 和 CLion 的使用体验差距显著,CLion copilot 的 Agent 效果很不好。(2025-07-19)
直接将第三方库源码放入项目而非使用依赖管理工具,很容易在较短的时间就内出现兼容性问题。 Mysvac · Pull Request #503 · BoomingTech/Piccolo
std::string 自C++17起终于要求内存严格连续,因此提供了非const版本的data(),可以直接写入数据,简化了文本数据的定量读取。
tinyobjloader 关于模块接口文件 PR :“C++20 is not widely used as of 2025. I might merge the PR after 3~4 years later.” 。这样 C++ 社区如何能够现代化 ε=(´ο`*))),难怪会出现 Rust 。
今天迷枵“狠狠地”制作了 tinyobjloader、 stb_image、 glfw 的模块接口文件。(`⌒´メ)
如果 const auto
推导出是指针类型,那么 const
修饰的是指针本身而非指针指向的对象。比如 int*
,推导出的结果是 int* const
而非 const int*
。同理,如果你将某种指针类型 T*
别名为 K
,则 const K
实际是 T* const
而非 const T*
。
咕一天,参加匹诺康尼的圣杯战争o(* ̄▽ ̄*)o
目前 Edge 浏览器的 PDF 查看功能存在严重 BUG,很多 PDF 会被显示为全白页面。这是一项实验性功能导致的,你可以在 Edge 的网址栏输入 edge://flags/#edge-new-pdf-viewer
前往实验功能面板,第一个就是 “New PDF Viewer(#edge-new-pdf-viewer)” ,将其关闭并重启浏览器即可解决问题。
C++20的模块接口文件,编译为动态链接库时依然需要编译器相关的导出符号,比如MSVC的 __declspec(dllexport)
某些软件的缓存默认在C盘,而且根本不会清理。比如网易云音乐,刚刚一查发现它的缓存占了迷枵的C盘50GB。。。
某种意义上,学的越多会的越少
迷枵以 1 分(罚时)的极大优势痛失银牌,荣获铜牌第一💦💦💦
Outlook的垃圾邮件检测机制极差,只要邮件有中文,基本就会被认为是垃圾邮件。重点的还没地方可以调整检查机制
手机QQ(安卓),动态页面上方的“游戏中心”终于可以不显示了,在“动态页面-更多-管理”中调整。以前强制显示游戏中心,还总是有无法关闭的红点。
即使你使用了C++20的模块化,你依然应该将声明与实现分离!!模块接口文件 .ixx/.cppm
要求顺序编译,如果你不分离声明与实现,一旦修改上层模块,就需要重新顺序地编译全部下层模块文件,极其耗时。注意 .cpp
文件可以轻松并行编译,如果模块接口仅含声明和少部分内联函数、将大部分实现代码放在 .cpp
文件,因为修改 .cpp
文件不会影响模块声明和文件,其他文件不需要重编译,更新项目耗时极短。如果你尝试使用标准库库模块(不需要编译标准库头文件),并分离模块接口文件与实现文件,将看到极快的编译速度。
Windows 11 的“快速启动”设置曾存在一些问题,可能占用超高内存,不知道现在是否修复。迷枵的笔记本32GB内存,曾因为它出现过开机占用即90%+的问题。
Minecraft 中的实体的碰撞箱并不会“转向”,永远是对齐坐标系的长方体。因此,即使是像“马”这样的对象,碰撞箱的长和宽也是相等的(防止马朝向不同时碰撞箱不同)。
《影之实力者》小说已经很久很久很久没更新了。。。
编程语言的 for 循环可以分为“基于范围”和“基于条件”,而某些现代语言只有范围 for (比如Py、Rust等)。这里依然以C++为例,for 循环最常被用于遍历数组对象,而范围 for 遍历数组的效率略高于条件 for (虽然差距较小)!!这是因为范围 for 基于数组子元素的指针,可以直接找到元素位置;而条件 for 通常使用索引访问数组元素,每次访问都需要根据索引进行寻址。
各类“前端”工具的设计思路是基本一致的,使用一种标记语言(HTML/XML/QML)描述(前台)界面,使用一种语言处理(后台)业务(JS/C#、Java、Kt/C++),然后使用事件(之类)的机制进行前后台的通信(Qt的signal与slot的本质也是如此)。标记语言很重要的一点是“组件化”,HTML本身并不支持自定义标签,这就是出现Vue等组件化框架的原因(之一)。
C++20的模块写起来确实很爽,但是不使用标准库时,只能将很多头文件放在全局模块片段。而模块本身依赖性导致不能完全并行编译(需拓扑排序),直接结果就是编译速度不升反降。
CLion会在编译时自动设置一些环境变量,然后就可能找错东西,比如 VCPKG_ROOT 指向 Visual Studio 自带的 vcpkg 路径,而不是手动安装设置的。
有一种奇怪的临时(较大)整数乘法:
using ull = unsigned long long; ull bmul(ull a, ull b, ull m) { ull c = a * b - (ull)((long double)a / m * b + 0.5L) * m; if (c < m) return c; return c + m; }
Windows 可以启用全局 UTF-8 默认编码,但是某些软件居然不支持,比如图吧工具箱就会乱码。
一个经典的表情包有什么重要特征?一定是某种特殊的“糊”。现在的表情包大概不会变绿,但还是可能因压缩变糊。仔细观察,特别是黑白的经典表情包(样例),可以看出波纹状的噪音,这被称为“振铃效应”,常因“理想低通滤波”产生。
Visual Studio 真是玄学,迷枵的win10台式机完全无法用 Visual Studio 运行 CMake 项目,但是用 VSCode 或 CLion 自动找到 MSVC 工具链并使用就一切正常,win11的笔记本也没有这个问题。
34分钟380MB和5分钟70MB的两个1080P(mp4)视频,直接前后拼接(使用clipchamp)合成1080P(mp4)新视频,会有多大?答案是11760MB。。。
WordPress默认开启/xmlrpc.php用于远程更新博客内容,有些人会利用此服务攻击博客。实际上你大概率用不到它(网页后台未使用此接口),可以使用Nginx拦截甚至301转发对此链接的访问。“不要惹我,不然我就把这些垃圾请求都转发到你的网站!(误)”
迷枵向OI-WIKI提交的“语言基础 – C++进阶 – 新版C++特性”内容修改已被合并,也算是为OI-WIKI贡献了万分之一的内容了。
一些语言用可以用 _
接受弃用的值,而C++(11起)有个 std::ignore
变量能做到类似的事,它实现方式非常简单:
struct _Ignore { // std::ignore 的类型 template <class _Ty> constexpr const _Ignore& operator=(const _Ty&) const noexcept { // 能够接受任何类型的赋值运算符重载 return *this; // 什么都不做 } };
前几天的蓝桥杯国赛,似乎没给迷枵发短袖(国赛纪念品)。。。
CS自学指南 是个很好的网站,正如其名“CS(计算机科学)”,理论内容居多。迷枵认为它缺少了一些更加“实践”的知识,比如非关系数据库、嵌入式与移动应用相关、测试相关、容器化集群,以及所有知识在实际应用中涉及的框架/程序。这才是完整的 CS&CT — 计算机科学与技术。
《陈凭案游记》已经45天未更新了
C++26标准大体有如下内容:静态(编译期)反射、SIMD标准库、线性代数标准库、诊断调试库、契约(前置与后置断言)、更高级的多线程/并发支持。大概是因为并发库的巨大更新,标准网络库被推迟了(调整实现方式)。(希望C++29能够见到标准网络库,不然迷枵真要被迫转向Rust了。)
C++标准库的有序容器与算法使用<
运算符,其他比较都由它实现,因此你的<
定义必须满足严格弱序,而初学者很容易因为<=
等写法违背此要求。而C++20引入了被戏称为“宇宙飞船运算符”的 <=>
,现在只需定义<=>
和==
就能自动生成其他比较运算,不必担心严格弱序问题。
C++23提供了标准库模块(目前仍是实验性),它与标准库头文件存在某种奇怪的关系:
#include <iostream> import std; // 正常运行
import std; #include <iostream> // 编译失败,重定义
C++的lamdba表达式生成的是一个匿名(非联合非聚合)类类型的对象,所以你可以通过 decltype()
获取对象类型。以前此类型默认构造必然为 delete
;但自C++20 起,lambda表达式捕获列表为空时,默认构造为 default
,所以你可以写出这样的代码:
decltype([](int x,int y){return x < y;}) less; // 创建一个类对象 std::cout << less(1, 2); // 输出 1 std::set< int, decltype([](const int x, const int y){return x > y;}) > my_set; // 直接在模板形参输入lambda表达式的类型,自定义set使用的比较运算
现在很多WIKI都选择使用mkdocs框架和material-mkdocs主题。如果你在OI-WIKI页面打开控制台,会发现有一行404报错。这是因为此主题在指定了仓库地址时会自动获取Stars数、forks数和最新release名,但OI-WIKI没有任何release。这完全不影响界面加载,但控制台报错令人不满,可惜目前还没有简单的配置项用于关闭release检索。
时间复杂度的大 O 符号的实际定义指得是大于等于上界的整个范围。比如归并排序的大O可以写作O(N*logN)、也可以写作O(2^N),因为O(2^N)>O(N*logN)。但是你不应该使用后者,实际使用大O表示的即使不是最紧上界也应该接近最紧上界,否则应该使用“复杂度小于O(…)”这样的表达。
GAMES104课程的Piccolo引擎,使用的第三方库和Vulkan-tutorial的内容基本一致(Vulkan + GLM + GLFW + STB + tinyobjloader + vulkanMemoryAllocator)。但是把第三方库代码直接放在了项目中,其中几个库的CMake配置现在过时。编译时可能需要修改GLM和tinyobjloader库的CMakeLists.txt,将CMake最小版本设为3.10以上。
微软的C++参考文档的网页title是C#文档(2025/06/07):C# 文档 – 入门、教程、参考。 | Microsoft Learn
编程语言的第一步是“Hello World!”,而图形学编程则是渲染三角形。但是使用Vulkan(C风格接口)绘制第一个三角形就需要900行代码!!(使用Vulkan-hpp(C++封装)或Vulkano(Rust封装)则需要约700行代码。)
下面的游戏有两个(纯策略)纳什均衡点:
UserY : S0 | UserY : S1 | |
UserX : S0 | 1 , 1 | 0 , 0 |
UserX : S1 | 0 , 0 | 0 , 0 |
米哈游启动器是用QT5做的。而VSCode是用Electron做的(用Electron做的都比 Visual Studio 用起来“流畅”)。
#include <iostream> struct A{ char a[2]{'3', '4'}; }; auto main() -> int{ const auto& [b] = A{}; std::cout << 1[b] << std::endl; }
上述代码的输出是4,这里涉及了哪些语法?
Cppreference中并没有“编译期多态/静态多态”这一概念。此概念一般指的是函数重载和运算符重载,Cppref中有重载决议和运算符重载章节,提供了极其细致的说明。这里的重点是,它并没有提及所谓的“编译期多态”概念。
所以有人粗读过Cppref但想不起来静态多态也很合理
你知不知道我知道你不知道我知道你不知道我不知道?