<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>文章 on ZZHX's Website</title><link>https://zzhx.cc/posts/</link><description>Recent content in 文章 on ZZHX's Website</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Thu, 29 Jan 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://zzhx.cc/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Anki 助力业余无线电等级考试刷题</title><link>https://zzhx.cc/posts/anki-helps-amateur-radio-exam-practice-questions/</link><pubDate>Thu, 29 Jan 2026 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/anki-helps-amateur-radio-exam-practice-questions/</guid><description>&lt;p&gt;题库版本：&lt;code&gt;v20250809&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;资源链接：&lt;a href="../../amateur_radio_class_b_exam_question_bank.7z"&gt;点击此处下载&lt;/a&gt;。含有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Anki 备份文件 (&lt;code&gt;amateur_radio_class_b_exam_question_bank.apkg&lt;/code&gt;)：可在 Anki 中直接导入，内置一个品相稍差的选择题模板，可按需替换调整；&lt;/li&gt;
&lt;li&gt;2025 年 B 类考试题库 txt 版 (&lt;code&gt;amateur_radio_class_b_exam_question_bank.txt&lt;/code&gt;)：从官方 pdf 题库中直接提取；&lt;/li&gt;
&lt;li&gt;2025 年 B 类考试题库 csv 版 (&lt;code&gt;amateur_radio_class_b_exam_question_bank.csv&lt;/code&gt;)：遵循标准 csv 格式，从 txt 版处理得到；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三者皆不含图片。图片题仅数道，建议单独学习。&lt;/p&gt;
&lt;p&gt;使用时既可以直接导入 Anki 备份文件版，也可以按需自行从 txt 或 csv 定制化。&lt;/p&gt;
&lt;p&gt;合理安排每天学习和复习的卡片数量，最短 4 天即可拿下。&lt;/p&gt;
&lt;p&gt;祝考试通过！73～&lt;/p&gt;</description></item><item><title>让 Clangd 支持 GCC 的 C++23 Std Module</title><link>https://zzhx.cc/posts/enable-clangd-cpp23-modules-with-gcc/</link><pubDate>Sat, 22 Nov 2025 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/enable-clangd-cpp23-modules-with-gcc/</guid><description>&lt;p&gt;本文主要记录在 Arch Linux 上使用 GCC 15.2.1 编译器编译包含 &lt;code&gt;import std;&lt;/code&gt; 的 C++23 标准模块（std module）代码时，如何让 Clangd 正常工作——即 &lt;code&gt;import std;&lt;/code&gt; 不再被标记为红色波浪线提示“Module &amp;lsquo;std&amp;rsquo; not found”，并且能够正常提供其中符号的悬停（Hover）提示。&lt;/p&gt;
&lt;p&gt;使用的工具版本如下：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - GCC: 15.2.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - Clangd: 22.0.0git def8ecbda9f146d5ba5bbc8c92f7d5ccd242ad2b
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - VS Code: 1.106.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - VS Code 中的 Clangd 插件: 0.2.0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - Bear: 3.1.6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如你所见，Clangd 官方目前最新的稳定版本是 21.1.6，但本次实验需自行从 Git 仓库编译开发中的 22.0.0 版本。实测表明，21.x 版本容易出现部分源代码文件中的符号无法正常解析的问题。&lt;/p&gt;
&lt;p&gt;VS Code 的 C++ 插件使用的是 Clangd（LLVM）。Microsoft 官方的 C/C++ 插件表现如何，可自行尝试。&lt;/p&gt;
&lt;p&gt;首先，我们创建一个最小可行项目。运行以下命令：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp /usr/include/c++/15.2.1/bits/std.cc .
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp /usr/include/c++/15.2.1/bits/std.compat.cc .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将系统中 GCC 提供的两个用于 C++23 标准模块的关键文件复制到当前目录。&lt;/p&gt;</description></item><item><title>C++ 标准中值类别的中文翻译</title><link>https://zzhx.cc/posts/translation-of-value-categories-in-cpp-standard/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/translation-of-value-categories-in-cpp-standard/</guid><description>&lt;p&gt;以下内容是《ISO/IEC 14882:2024》&lt;em&gt;[7.2.1]&lt;/em&gt; &lt;strong&gt;Value category&lt;/strong&gt; &lt;em&gt;[basic.lval]&lt;/em&gt; 部分的中文翻译。标准文件可从&lt;a href="https://github.com/zzhx2006/CPP_Standard"&gt;此仓库&lt;/a&gt;下载。&lt;/p&gt;
&lt;hr&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; expression 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; glvalue rvalue 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \ / \ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \ / \ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lvalue xvalue prvalue&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;glvalue（泛左值）是一个表达式，其求值结果决定了某个对象或函数的身份（identity）。&lt;/li&gt;
&lt;li&gt;prvalue（纯右值）是一个表达式，其求值用于初始化一个对象、或在特定上下文中计算某个运算符的操作数，或者是一个类型为 cv void 的表达式。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;xvalue（亡值）是一个 glvalue，它表示一个其资源可以被重用的对象（通常是因为该对象即将结束其生命周期）。&lt;/li&gt;
&lt;li&gt;lvalue（左值）是一个不是 xvalue 的 glvalue。&lt;/li&gt;
&lt;li&gt;rvalue（右值）是一个 prvalue 或者 xvalue。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每一条表达式恰好属于本分类体系中以下三种基本类别之一：lvalue、xvalue 或 prvalue。这种表达式的属性被称为它的值类别（value category）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注 1：&lt;/strong&gt; 第 &lt;em&gt;[7.6]&lt;/em&gt; 节中对每一个内建运算符的讨论，都指明了该运算符所产生的结果的值类别，以及它所期望的操作数的值类别。例如，内建的赋值运算符要求其左侧操作数为 lvalue，右侧操作数为 prvalue，并产生一个 lvalue 类型的结果。用户定义的运算符本质上是函数，其所接受的操作数和所产生的结果的值类别由其参数类型与返回类型决定。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注 2：&lt;/strong&gt; 历史上，lvalue 和 rvalue 这两个术语来源于它们通常出现在赋值表达式的左边或右边（尽管这一规则在现代语言规范中已不再普遍适用）；glvalue 是 “广义的” lvalue，prvalue 是 “纯正的” rvalue，而 xvalue 是 “将亡的” lvalue。尽管这些术语中包含 “值（value）”，但它们实际上是对表达式的分类，而非对实际数据值的描述。&lt;/p&gt;</description></item><item><title>核心 Linux Socket API 用法释义</title><link>https://zzhx.cc/posts/core-linux-socket-api-usage-explained/</link><pubDate>Wed, 05 Mar 2025 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/core-linux-socket-api-usage-explained/</guid><description>&lt;h3 id="1-socket"&gt;1. socket()&lt;/h3&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#6639ba"&gt;socket&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;协议族&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;套接字类型&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;协议&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;📖 解释&lt;/strong&gt;：创建一个新的套接字，返回一个文件描述符用于后续网络通信.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 1 个参数 🔑&lt;/strong&gt;：协议族，指定通信协议类型.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例：&lt;code&gt;AF_INET&lt;/code&gt;（IPv4协议）、&lt;code&gt;AF_INET6&lt;/code&gt;（IPv6协议）、&lt;code&gt;AF_UNIX&lt;/code&gt;（本地进程间通信）.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第 2 个参数 🔑&lt;/strong&gt;：套接字类型，指定通信语义.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例：&lt;code&gt;SOCK_STREAM&lt;/code&gt;（TCP流式套接字）、&lt;code&gt;SOCK_DGRAM&lt;/code&gt;（UDP数据报套接字）.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第 3 个参数 🔑&lt;/strong&gt;：具体协议，通常为0（使用默认协议）.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例：若类型是&lt;code&gt;SOCK_STREAM&lt;/code&gt;，则默认协议是&lt;code&gt;IPPROTO_TCP&lt;/code&gt;；若类型是&lt;code&gt;SOCK_DGRAM&lt;/code&gt;，默认协议是&lt;code&gt;IPPROTO_UDP&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;返回值 📤&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ 成功时：返回非负整数（套接字文件描述符）.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;❎ 失败时：返回-1，并设置&lt;code&gt;errno&lt;/code&gt;（如&lt;code&gt;EACCES&lt;/code&gt;权限不足、&lt;code&gt;EINVAL&lt;/code&gt;参数无效）.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="2-bind"&gt;2. bind()&lt;/h3&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#6639ba"&gt;bind&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;套接字描述符&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;const&lt;/span&gt; &lt;span style="color:#cf222e"&gt;struct&lt;/span&gt; sockaddr &lt;span style="color:#0550ae"&gt;*&lt;/span&gt;&lt;span style="color:#f6f8fa;background-color:#82071e"&gt;地址&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;socklen_t&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;地址长度&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;📖 解释&lt;/strong&gt;：将套接字与特定IP地址和端口绑定.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 1 个参数 🔑&lt;/strong&gt;：套接字描述符（通过&lt;code&gt;socket()&lt;/code&gt;创建的文件描述符）.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 2 个参数 🔑&lt;/strong&gt;：地址（指向&lt;code&gt;sockaddr&lt;/code&gt;结构的指针），包含IP和端口.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例：&lt;code&gt;struct sockaddr_in server_addr&lt;/code&gt;（IPv4地址结构），需填充&lt;code&gt;sin_family&lt;/code&gt;（&lt;code&gt;AF_INET&lt;/code&gt;）、&lt;code&gt;sin_port&lt;/code&gt;（&lt;code&gt;htons(8080)&lt;/code&gt;）、&lt;code&gt;sin_addr&lt;/code&gt;（&lt;code&gt;INADDR_ANY&lt;/code&gt; 表示监听所有接口）.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第 3 个参数 🔑&lt;/strong&gt;：地址长度（地址结构的大小）.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例：&lt;code&gt;sizeof(struct sockaddr_in)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;返回值 📤&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ 成功时：返回0.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;❎ 失败时：返回-1（如端口已被占用，&lt;code&gt;errno=EADDRINUSE&lt;/code&gt;）.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="3-listen"&gt;3. listen()&lt;/h3&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#6639ba"&gt;listen&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;套接字描述符&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;int&lt;/span&gt; &lt;span style="color:#f6f8fa;background-color:#82071e"&gt;积压连接数&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;📖 解释&lt;/strong&gt;：将套接字设为监听模式，等待客户端连接请求.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 1 个参数 🔑&lt;/strong&gt;：套接字描述符（已绑定的套接字）.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 2 个参数 🔑&lt;/strong&gt;：积压连接数（等待队列的最大长度）.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例：5（表示最多允许5个未处理的连接请求）.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;返回值 📤&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ 成功时：返回0.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;❎ 失败时：返回-1（如套接字未绑定，&lt;code&gt;errno=EINVAL&lt;/code&gt;）.&lt;/p&gt;</description></item><item><title>C++变参模板实战：递归继承实现简易元组类</title><link>https://zzhx.cc/posts/cpp-variadic-templates-recursive-inheritance-minimal-tuple/</link><pubDate>Thu, 28 Nov 2024 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/cpp-variadic-templates-recursive-inheritance-minimal-tuple/</guid><description>&lt;p&gt;详细的讲解请看 CppMore 里缪大佬的 &lt;a href="https://www.cppmore.com/2020/04/25/understanding-variadic-templates/"&gt;这篇文章&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;此处学习一下其中的使用 &lt;strong&gt;递归继承&lt;/strong&gt; 技巧实现简易元组类这个例子。&lt;/p&gt;
&lt;p&gt;直接 &amp;ldquo;Show me the code!&amp;rdquo;&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;#include&lt;/span&gt; &lt;span style="color:#57606a"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style="color:#57606a"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt; 先明晰省略运算符的意思：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt; typename... T --&amp;gt; 把一堆类型折叠到 T 中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt; T ... --&amp;gt; 从 T 中展开之前折叠的变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// #1: 先是 Tuple 类
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// 主模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;typename&lt;/span&gt;&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; Types&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;class&lt;/span&gt; &lt;span style="color:#1f2328"&gt;Tuple&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// 全特化：作为终止递归的条件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;class&lt;/span&gt; &lt;span style="color:#1f2328"&gt;Tuple&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; Head&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt;&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; Tail&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#57606a"&gt;// 将传递进来的参数分为第 1 个（称之为 Head）和其余个（第 2～N 个，折叠在 Tail 里）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;class&lt;/span&gt; &lt;span style="color:#1f2328"&gt;Tuple&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;Head&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tail&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#0550ae"&gt;:&lt;/span&gt; &lt;span style="color:#cf222e"&gt;public&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;Tail&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt; &lt;span style="color:#57606a"&gt;// 递归继承（采用公有继承）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;public&lt;/span&gt;&lt;span style="color:#0550ae"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Tuple&lt;span style="color:#1f2328"&gt;()&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Tuple&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;Head v&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tail&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; vtails&lt;span style="color:#1f2328"&gt;)&lt;/span&gt; &lt;span style="color:#0550ae"&gt;:&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;Tail&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;vtails&lt;span style="color:#1f2328"&gt;...),&lt;/span&gt; head_&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;v&lt;span style="color:#1f2328"&gt;)&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#57606a"&gt;// 用来返回 Tuple 类的内部成员 head_ 的值，也是这个 Tuple 的第一个值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Head &lt;span style="color:#0550ae"&gt;&amp;amp;&lt;/span&gt;head&lt;span style="color:#1f2328"&gt;()&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt; &lt;span style="color:#cf222e"&gt;return&lt;/span&gt; head_&lt;span style="color:#1f2328"&gt;;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;protected&lt;/span&gt;&lt;span style="color:#0550ae"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#57606a"&gt;// head_ : 第一个值的意思，比如作为 Tuple&amp;lt;int, float, char&amp;gt; t(5, 2.7, &amp;#39;b&amp;#39;) 其中的 5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Head head_&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// #2: 然后是 TupleAt 类
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// 主模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;size_t I&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt;&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; TList&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;struct&lt;/span&gt; &lt;span style="color:#1f2328"&gt;TupleAt&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// 暂称 Tuple&amp;lt;T, TList...&amp;gt; 叫做“当前元组”
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// 设计 TupleAt 的目的是获取到指定索引（I）处的元素的类型（称之为ValueType）（不必获取到具体的值，这个任务交给 Tuple 类的 head() 方法解决）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// ValueType 是“尾随元组”（意思是当前元组把第一项元素去掉，剩余的元素构成的元组）的第一个元素的类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// TupleType 是“尾随元组”这一整体类型（它是当前元组的父类，因为 Tuple&amp;lt;Head, Tail...&amp;gt; 公有继承了 Tuple&amp;lt;Tail...&amp;gt;）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;size_t I&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; T&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt;&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; TList&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;struct&lt;/span&gt; &lt;span style="color:#1f2328"&gt;TupleAt&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;I&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;T&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; ValueType &lt;span style="color:#0550ae"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; TupleAt&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;I &lt;span style="color:#0550ae"&gt;-&lt;/span&gt; &lt;span style="color:#0550ae"&gt;1&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&amp;gt;::&lt;/span&gt;ValueType&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; TupleType &lt;span style="color:#0550ae"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; TupleAt&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;I &lt;span style="color:#0550ae"&gt;-&lt;/span&gt; &lt;span style="color:#0550ae"&gt;1&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&amp;gt;::&lt;/span&gt;TupleType&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// 作为终止递归的条件：I = 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; T&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt;&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; TList&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;struct&lt;/span&gt; &lt;span style="color:#1f2328"&gt;TupleAt&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0550ae"&gt;0&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;T&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; ValueType &lt;span style="color:#0550ae"&gt;=&lt;/span&gt; T&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; TupleType &lt;span style="color:#0550ae"&gt;=&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;T&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;// #3: 最后还剩个 TupleGet 函数模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;/* TupleGet&amp;lt;I&amp;gt;(tuple) 这个函数模板在使用的时候（比如 TupleGet&amp;lt;2&amp;gt;(t)）直观上接受两个参数：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt; 其一，是模板参数 std::size_t I，表示索引；
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt; 其二，是函数参数 Tuple&amp;lt;TList...&amp;gt;&amp;amp; tuple，表示目标元组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt; TList 是目标元组 tuple 的模板参数们
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#57606a"&gt;*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;template&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;size_t I&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt;&lt;span style="color:#1f2328"&gt;...&lt;/span&gt; TList&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; TupleAt&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;I&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&amp;gt;::&lt;/span&gt;ValueType &lt;span style="color:#0550ae"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TupleGet&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;amp;&lt;/span&gt;tuple&lt;span style="color:#1f2328"&gt;)&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;using&lt;/span&gt; BaseTupleType &lt;span style="color:#0550ae"&gt;=&lt;/span&gt; &lt;span style="color:#cf222e"&gt;typename&lt;/span&gt; TupleAt&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;I&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;TList&lt;span style="color:#1f2328"&gt;...&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&amp;gt;::&lt;/span&gt;TupleType&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;return&lt;/span&gt; &lt;span style="color:#cf222e"&gt;static_cast&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;BaseTupleType &lt;span style="color:#0550ae"&gt;&amp;amp;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;tuple&lt;span style="color:#1f2328"&gt;).&lt;/span&gt;head&lt;span style="color:#1f2328"&gt;();&lt;/span&gt; &lt;span style="color:#57606a"&gt;// 把当前元组强制转换其类型为上一层元组（也就是当前元组的尾随元组），.head() 的结果就会变成尾随元组的 head_
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6639ba"&gt;main&lt;/span&gt;&lt;span style="color:#1f2328"&gt;()&lt;/span&gt; &lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;float&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;char&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt; t&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#0550ae"&gt;1&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0550ae"&gt;2.7&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0a3069"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; Tuple&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#cf222e"&gt;int&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;float&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;char&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#cf222e"&gt;double&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt; t2&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;&lt;span style="color:#0550ae"&gt;4&lt;/span&gt;&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; t&lt;span style="color:#1f2328"&gt;,&lt;/span&gt; &lt;span style="color:#0550ae"&gt;4.7&lt;/span&gt;&lt;span style="color:#1f2328"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;cout &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; TupleGet&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0550ae"&gt;2&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;t&lt;span style="color:#1f2328"&gt;)&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;endl&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;cout &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; TupleGet&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0550ae"&gt;0&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;t2&lt;span style="color:#1f2328"&gt;)&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;endl&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;cout &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; TupleGet&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0550ae"&gt;2&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;t2&lt;span style="color:#1f2328"&gt;)&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;endl&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;cout &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; TupleGet&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0550ae"&gt;2&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;TupleGet&lt;span style="color:#0550ae"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0550ae"&gt;1&lt;/span&gt;&lt;span style="color:#0550ae"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#1f2328"&gt;(&lt;/span&gt;t2&lt;span style="color:#1f2328"&gt;))&lt;/span&gt; &lt;span style="color:#0550ae"&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style="color:#0550ae"&gt;::&lt;/span&gt;endl&lt;span style="color:#1f2328"&gt;;&lt;/span&gt; &lt;span style="color:#57606a"&gt;// 嵌套元组也能正常处理哦
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#cf222e"&gt;return&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个程序实现了一个极简元组类，可以把不同类型的元素绑定在一起，并按下表索引访问元素。&lt;/p&gt;</description></item><item><title>在 Arch Linux 上编译 bloomberg/clang-p2996 小记</title><link>https://zzhx.cc/posts/compiling-clang-p2996-on-arch-linux/</link><pubDate>Sun, 24 Nov 2024 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/compiling-clang-p2996-on-arch-linux/</guid><description>&lt;p&gt;本文简要记录笔者在 Arch Linux 上编译一个部分支持 C++ 反射的 clang 编译器的过程。&lt;/p&gt;
&lt;p&gt;期待 Reflection 能正式被编译器实现的那一天。 :)&lt;/p&gt;
&lt;p&gt;本次实验受群友 Yiran Wang 启发。&lt;/p&gt;
&lt;h2 id="克隆仓库"&gt;克隆仓库&lt;/h2&gt;
&lt;p&gt;GitHub 仓库在 &lt;a href="https://github.com/bloomberg/clang-p2996/tree/p2996"&gt;这里&lt;/a&gt;，有关这个编译器的介绍详情请看仓库（默认是 purpose 分支，代码在 p2996 分支上）。&lt;/p&gt;
&lt;p&gt;先克隆仓库到本地：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ git clone https://github.com/bloomberg/clang-p2996 --depth &lt;span style="color:#0550ae"&gt;1&lt;/span&gt; --branch&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;p2996&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用 &lt;code&gt;--depth 1&lt;/code&gt; 选项只克隆最新版本的 commit，可大大减小仓库体积（好像只有两百多兆）。&lt;/p&gt;
&lt;p&gt;有的仓库有很多分支（比如 llvm 或者 gcc 官方仓库），使用 &lt;code&gt;--branch=xxx&lt;/code&gt; 指定克隆某一个分支也可以减小体积。本仓库只有两个分支，作用不大。&lt;/p&gt;
&lt;p&gt;建议上网搜一下镜像站，在高级搜索中调整搜索范围为近一周左右，基本就可以找到可用的镜像站，实测有助于提高网速。&lt;/p&gt;
&lt;h2 id="编译-clang"&gt;编译 Clang&lt;/h2&gt;
&lt;p&gt;编译选项和步骤可以参考 &lt;a href="https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm"&gt;llvm 官网手册中的介绍&lt;/a&gt;，此处给出我的生成命令，供参考：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ &lt;span style="color:#6639ba"&gt;cd&lt;/span&gt; clang-p2996
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mkdir build
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ &lt;span style="color:#6639ba"&gt;cd&lt;/span&gt; build
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ cmake -DLLVM_ENABLE_PROJECTS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;clang &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DCMAKE_C_COMPILER&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;clang &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DCMAKE_CXX_COMPILER&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;clang++ &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_ENABLE_RUNTIMES&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;&lt;span style="color:#0a3069"&gt;&amp;#34;libc;libcxx;libcxxabi;libunwind&amp;#34;&lt;/span&gt; &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DCMAKE_C_FLAGS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;&lt;span style="color:#0a3069"&gt;&amp;#34;-O3 -march=native -mtune=native&amp;#34;&lt;/span&gt; &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DCMAKE_CXX_FLAGS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;&lt;span style="color:#0a3069"&gt;&amp;#34;-O3 -march=native -mtune=native&amp;#34;&lt;/span&gt; &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DCMAKE_BUILD_TYPE&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;Release &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_USE_LINKER&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;lld &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_BUILD_TOOLS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;OFF &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_BUILD_EXAMPLES&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;OFF &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_BUILD_TESTS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;OFF &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_INCLUDE_TESTS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;OFF &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_INCLUDE_DOCS&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;OFF &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DLLVM_TARGETS_TO_BUILD&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;&lt;span style="color:#0a3069"&gt;&amp;#34;X86&amp;#34;&lt;/span&gt; &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -DCMAKE_INSTALL_PREFIX&lt;span style="color:#0550ae"&gt;=&lt;/span&gt;/usr/local/llvm-build &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -G &lt;span style="color:#0a3069"&gt;&amp;#34;Unix Makefiles&amp;#34;&lt;/span&gt; &lt;span style="color:#0a3069"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ../llvm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;具体每一个选项是什么意思以及有哪些可选参数，自己 STFW 或者问 AI。此处仅为精简编译（仅编译 clang），没有添加其他的各种工具。有需者请自选。&lt;/p&gt;</description></item><item><title>C++ &lt;chrono&gt; 库中的高效闰年判断算法解析</title><link>https://zzhx.cc/posts/efficient-leap-year-check-cpp-chrono-optimization/</link><pubDate>Tue, 08 Oct 2024 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/efficient-leap-year-check-cpp-chrono-optimization/</guid><description>&lt;p&gt;在 C++ &lt;code&gt;&amp;lt;chrono&amp;gt;&lt;/code&gt; 库中，有如下判断闰年的算法：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;class&lt;/span&gt; &lt;span style="color:#1f2328"&gt;year&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;private&lt;/span&gt;&lt;span style="color:#0550ae"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#cf222e"&gt;short&lt;/span&gt; _M_y&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;public&lt;/span&gt;&lt;span style="color:#0550ae"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#cf222e"&gt;constexpr&lt;/span&gt; &lt;span style="color:#cf222e"&gt;bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	is_leap&lt;span style="color:#1f2328"&gt;()&lt;/span&gt; &lt;span style="color:#cf222e"&gt;const&lt;/span&gt; &lt;span style="color:#cf222e"&gt;noexcept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#1f2328"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#cf222e"&gt;return&lt;/span&gt; &lt;span style="color:#1f2328"&gt;(&lt;/span&gt;_M_y &lt;span style="color:#0550ae"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#1f2328"&gt;(&lt;/span&gt;_M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;25&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt; &lt;span style="color:#0550ae"&gt;?&lt;/span&gt; &lt;span style="color:#0550ae"&gt;15&lt;/span&gt; &lt;span style="color:#0550ae"&gt;:&lt;/span&gt; &lt;span style="color:#0550ae"&gt;3&lt;/span&gt;&lt;span style="color:#1f2328"&gt;))&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#1f2328"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#1f2328"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;根据源代码的注释，总结一下优化思路：&lt;/p&gt;
&lt;p&gt;判断闰年的规则是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果年份能被 4 整除且不能被 100 整除，则是闰年.&lt;/li&gt;
&lt;li&gt;如果年份能被 100 整除，则还必须能被 400 整除，才是闰年.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先判断能否被 100 整除比其他思路更快，因为它减少了不必要的计算. 参考&lt;a href="https://github.com/cassioneri/calendar"&gt;这里&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;所以，逻辑优化成了：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;return&lt;/span&gt; _M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;100&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt; &lt;span style="color:#0550ae"&gt;?&lt;/span&gt; _M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;400&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt; &lt;span style="color:#0550ae"&gt;:&lt;/span&gt; _M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;4&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当知道一个数字能被 100 整除时，能被 400 整除实际上意味着它也可以被 16 整除.&lt;/p&gt;
&lt;p&gt;标准库在第一步判断时没有使用 100 而是 25，因为检查被 25 整除的速度更快（汇编少了一句，参考&lt;a href="https://godbolt.org/z/55G8rn77e"&gt;这里&lt;/a&gt;），而且仍然管用.&lt;/p&gt;
&lt;p&gt;因此，进一步优化为：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#cf222e"&gt;return&lt;/span&gt; _M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;25&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt; &lt;span style="color:#0550ae"&gt;?&lt;/span&gt; _M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;16&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt; &lt;span style="color:#0550ae"&gt;:&lt;/span&gt; _M_y &lt;span style="color:#0550ae"&gt;%&lt;/span&gt; &lt;span style="color:#0550ae"&gt;4&lt;/span&gt; &lt;span style="color:#0550ae"&gt;==&lt;/span&gt; &lt;span style="color:#0550ae"&gt;0&lt;/span&gt;&lt;span style="color:#1f2328"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果一个数不能被 4 整除，那么它肯定也不能被 16 整除，所以在这种情况下，无论能否被 25 整除，都应该返回 &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果一个数能被 4 整除，那么它能被 25 整除当且仅当它能被 100 整除. 这是因为任何能被 25 整除的数都是以 00、25、50 或 75 结尾的，而只有以 00 结尾的数也能被 100 整除.&lt;/p&gt;</description></item><item><title>如何为 gcc 贡献中文翻译</title><link>https://zzhx.cc/posts/how-to-contribute-chinese-translation-for-gcc/</link><pubDate>Sat, 14 Sep 2024 00:00:00 +0800</pubDate><guid>https://zzhx.cc/posts/how-to-contribute-chinese-translation-for-gcc/</guid><description>&lt;h2 id="在本地试验"&gt;在本地试验&lt;/h2&gt;
&lt;p&gt;先在本地试一试修改 gcc 的翻译吧. 新建一个用来折腾的文件夹 &lt;code&gt;~/test/&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mkdir ~/test
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ &lt;span style="color:#6639ba"&gt;cd&lt;/span&gt; ~/test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="下载最新翻译"&gt;下载最新翻译&lt;/h3&gt;
&lt;p&gt;下载 Translation Project 上的最新版 gcc 简体中文翻译文件. 截至发稿时，gcc 最新版本为 14.2.0 版.&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ wget https://translationproject.org/PO-files/zh_CN/gcc-14.2.0.zh_CN.po&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下载了一个叫做 gcc-14.2.0.zh_CN.po 的文件.&lt;/p&gt;
&lt;p&gt;关于 Translation Project，AI 是这样介绍的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GNU 翻译项目（GNU Translation Project）是一项由社区推动的倡议，致力于将 GNU 软件的用户界面、文档和手册翻译成多种语言，以实现软件的国际化和本地化. 该项目欢迎志愿者参与，提供翻译工具和资源，旨在确保自由软件能够跨越语言障碍，惠及全球用户，增强其可及性和用户体验.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;gcc 的最新版翻译文件和其他语言翻译可以在&lt;a href="https://translationproject.org/domain/gcc.html"&gt;这里&lt;/a&gt;找到；其他软件的翻译项目可以在&lt;a href="https://translationproject.org/domain/index.html"&gt;这里&lt;/a&gt;找到. 这些都可以在&lt;a href="https://translationproject.org/html/welcome.html"&gt;官网&lt;/a&gt;找到，我们先暂时不管它们.&lt;/p&gt;
&lt;h3 id="编辑翻译文件"&gt;编辑翻译文件&lt;/h3&gt;
&lt;p&gt;接下来需要编辑这个 .po 文件，选择其中的词条（称为 &lt;code&gt;msgid&lt;/code&gt;）翻译成中文（在 &lt;code&gt;msgstr&lt;/code&gt;）.&lt;/p&gt;
&lt;p&gt;当然可以用文本编辑器直接开干. 更推荐的是用专门的编辑 .po 文件的软件来干活更方便啦.&lt;/p&gt;
&lt;p&gt;这里推荐使用 Poedit 软件. 下载安装（比如 Arch Linux；其他各发行版请使用各自的工具安装）：&lt;/p&gt;

&lt;pre class="code_block"&gt;&lt;code&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo pacman -S poedit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后右键点击 gcc-14.2.0.zh_CN.po，选择“使用 Poedit 打开”.&lt;/p&gt;
&lt;figure&gt;
 &lt;img src="img1.avif" alt="选择“使用 Poedit 打开”" &gt;&lt;figcaption&gt;使用 Poedit 打开&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;可以看到如下的工作区. 其中没有中文的黑色条目是缺少翻译的；有中文但黄色字体的是“需要处理”的（带“fuzzy”标签），表示中文翻译仍不准确，需要修改.&lt;/p&gt;
&lt;figure&gt;
 &lt;img src="img2.avif" alt="Poedit 页面" &gt;&lt;figcaption&gt;Poedit 页面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;黄色的条目即使有中文翻译，但是被标记了 fuzzy 标签（Poedit 显示“需要处理”），最终仍不会显示出来.&lt;/p&gt;</description></item></channel></rss>