自 C++11 起,C++ 经历了一场脱胎换骨的现代化变革。移动语义、Lambda、智能指针让 C++ 从"带类的 C"演变为一门表达能力媲美高层语言的系统级语言;C++20 的 Concepts、Ranges、Coroutines 三大特性更是将 C++ 推向了新的抽象高度;C++23 和即将到来的 C++26 则继续在并发、容器、类型系统等方向深耕。
本专题旨在逐一解剖这些关键特性——不讲"是什么"的表层,而是追问"为什么这样设计""编译器在背后做了什么""正确用法和致命陷阱分别在哪里"。
自 C++11 起,C++ 经历了一场脱胎换骨的现代化变革。移动语义、Lambda、智能指针让 C++ 从"带类的 C"演变为一门表达能力媲美高层语言的系统级语言;C++20 的 Concepts、Ranges、Coroutines 三大特性更是将 C++ 推向了新的抽象高度;C++23 和即将到来的 C++26 则继续在并发、容器、类型系统等方向深耕。
本专题旨在逐一解剖这些关键特性——不讲"是什么"的表层,而是追问"为什么这样设计""编译器在背后做了什么""正确用法和致命陷阱分别在哪里"。
在这个 AI 爆发的时代,GPU 编程已经成为高性能计算和深度学习系统的基石。然而,许多开发者对 CUDA 的理解仅停留在调用 PyTorch 或 Triton 的层面。
本专题 (LeetGPU) 旨在通过一系列由浅入深的编程挑战,带你亲手实现从基础向量加法到 GPT-2 Transformer Block 的核心算子。每一个挑战都不仅是代码实现,更是对并行计算思维、内存层次结构和硬件特性的深度探索。
特别值得强调的是,从 CPU 到 GPU 的编程思维转变,核心在于从“以指令为中心”转向“以数据为中心”,以及在具体算子实现中灵活运用“以输入为中心(Input-centric / Scatter)”与“以输出为中心(Output-centric / Gather)”的计算模式。理解这些模式的适用场景(如写冲突处理、访存合并等),是写出高性能 Kernel 的关键。
在大模型(LLM)风起云涌的今天,我们往往只关注参数量(7B, 65B, 175B)和模型效果。但作为工程师和研究者,我们更应该深入了解 Transformer 这个“地基”下的每一块砖瓦。
本专题旨在深入剖析 Transformer 架构中那些容易被忽视,但却至关重要的细节。从数值稳定性到几何直觉,从内存优化到理论缺陷,带你重新认识这个改变了 AI 历史的模型。
C++11 引入 auto 和 decltype 之后,"类型"不再总是需要用手写。但这套推导规则有三个不同机制——auto、decltype(auto)、decltype(expression)——它们各自按不同的逻辑工作。更微妙的是,当 auto&& 遇到万能引用,或者 decltype 遇到括号,行为会发生令人意外的翻转。
本文从模板实参推导的规则出发,把这三条推导路径的差异,以及日常使用中最容易踩的坑,逐一说清楚。
模板是 C++ 泛型编程的基石,但 C++98 到 C++17 的模板一直有一个核心痛点:对模板参数的要求隐藏在函数体内,只有当用户传入不正确的类型时,才在实例化阶段爆出数页深不可测的错误信息。 SFINAE、enable_if、static_assert 都是在这条链路上打补丁。
C++20 Concepts 从根本上改变了这一点。它让"模板参数必须满足什么条件"成为了接口的显式部分。
在 C++98 时代,编译期计算几乎等同于模板元编程(TMP)——用递归模板 + 特化在类型系统里模拟图灵完备的计算。代码晦涩,编译慢,出错信息堪称灾难。C++11 引入了 constexpr,承诺让"正常 C++ 代码"在编译期运行。此后每一个标准版本都在放宽它的能力边界,到 C++20/23,你几乎可以在编译期做任何事。
本文梳理 constexpr 从 C++11 到 C++23 的演进历程,重点解释 if constexpr、consteval、constinit 三个极易混淆的概念,以及编译期容器的内存模型。
C++20 引入的协程(Coroutines)是最受期待也最让人困惑的特性之一。它不像其他语言那样提供一个开箱即用的"async/await"运行时——C++ 的协程是一套可定制的基础设施,三个关键字(co_await、co_return、co_yield)和一套 Promise/Awaiter 协议构成了一个编译器变换框架,库作者在此基础上构建具体的协程类型(如 generator<T>、task<T>)。
本文从"编译器把协程函数变成了什么"出发,拆开协程帧(coroutine frame)、Promise 类型、Awaiter 协议和 HALO 优化,帮你建立起对 C++ 协程运行时行为的精确心智模型。
C++ 的零拷贝(zero-copy)设计哲学有一条清晰的演进路线:从 C 语言的裸指针,到 C++98 的引用,再到 C++17 的 string_view 和 C++20 的 span<T>。这条路的终点是:函数参数只描述"我读什么",而不参与所有权决策,也不触发拷贝和分配。
与零拷贝参数字段平行发展的,是标准库对操作系统设施的封装——C++17 的 <filesystem> 第一次让目录遍历、路径操作、文件属性查询成为了标准 C++,不再依赖 POSIX 或 Win32 API。
如果说 C++11 是一次"革命"(移动语义、Lambda、智能指针),C++20 是一次"进化"(Concepts、Ranges、Coroutines),那么 C++17 的核心贡献是语法上的精耕细作——没有改变语言的根本表达范式,但在大量日常编码路径上,把繁琐的手写代码变成了编译器自动推导。
本文详述 C++17 三大语法糖:结构化绑定、折叠表达式和类模板实参推导(CTAD),它们各自只涉及很少的语法规则,但覆盖了极其广阔的日常使用场景。
C++17 没有 C++20 那种"换代级"的大语法(Concepts/Ranges/Coroutines),但它引入了一组极大改善日常表达力的类型——variant、optional 和 any。三个类型分别对应三种不同的运行时不确定性:
optional<T>:要么有 T,要么没有("可空的值")variant<Ts...>:是 Ts 中的恰好一种("多个可能类型中的一个")any:可以是任意可拷贝类型("完全放弃类型信息")这三者一起,构成了从"最确定"(optional)到"最灵活"(any)的运行时多态谱系。其中 variant 最为精妙——它不仅是 C++ 对 sum type 的首次标准实现,还带着一套 std::visit 的模式匹配机制。