<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>学习笔记 on T.本秋的自留地</title>
    <link>https://blog.texsd.eu.org/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
    <description>Recent content in 学习笔记 on T.本秋的自留地</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-cn</language>
    <copyright>Copyright© 2026 T.本秋. Licensed under CC BY-NC-SA 4.0.</copyright>
    <lastBuildDate>Thu, 13 Nov 2025 13:58:39 +0800</lastBuildDate><atom:link href="https://blog.texsd.eu.org/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>现代 C&#43;&#43; 笔记：I/O 流与字符串流</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-10-io-streams/</link>
      <pubDate>Thu, 13 Nov 2025 13:58:39 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-10-io-streams/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;流
    &lt;div id=&#34;流&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%b5%81&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;

&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;std::cin &amp;gt;&amp;gt;&lt;/code&gt;
    &lt;div id=&#34;stdcin-&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdcin-&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;跳过输入流中前导空白符，当遇到下一个空白的时候停止，并把空白&lt;strong&gt;保留&lt;/strong&gt;在输入缓冲区中。&lt;/p&gt;
&lt;p&gt;简单来说，就是获取一个单词。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;C-style 的函数
    &lt;div id=&#34;c-style-的函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#c-style-%e7%9a%84%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;有一些函数是 C 遗留下来的，所以他们不支持 &lt;code&gt;std::string&lt;/code&gt;，只能使用传统的 C 风格字符串。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;std::getline()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;给定一个字符串缓冲的容器：&lt;/p&gt;
&lt;p&gt;获取缓冲区的内容，直到遇到 &lt;code&gt;\n&lt;/code&gt;，把 &lt;code&gt;\n&lt;/code&gt; 以及前面的内容提取，然后&lt;strong&gt;不将&lt;/strong&gt; &lt;code&gt;\n&lt;/code&gt; 放在目标中。&lt;/p&gt;
&lt;p&gt;重载函数 &lt;code&gt;(strBuf, n)&lt;/code&gt; 可以提取指定的长度的字符，获取 &lt;code&gt;n -1&lt;/code&gt; 个字符，因为要有 &lt;code&gt;\0&lt;/code&gt; 结尾。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gcount()&lt;/code&gt; 用于统计提取的部分，包括 &lt;code&gt;\n&lt;/code&gt;，但是不包括限定长度在后面添加的 &lt;code&gt;\0&lt;/code&gt;。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：继承、虚函数与异常处理</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-9-inheritance-virtual-exceptions/</link>
      <pubDate>Thu, 06 Nov 2025 10:23:35 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-9-inheritance-virtual-exceptions/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;继承，派生
    &lt;div id=&#34;继承派生&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%a7%e6%89%bf%e6%b4%be%e7%94%9f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;

&lt;h3 class=&#34;relative group&#34;&gt;继承初始化
    &lt;div id=&#34;继承初始化&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%a7%e6%89%bf%e5%88%9d%e5%a7%8b%e5%8c%96&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;在构造函数后面的 &lt;code&gt;:&lt;/code&gt; 加入基类的列表初始化：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Base&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_baseVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;baseVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_baseVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;baseVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Derive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_deriveVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Derive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;baseVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deriveVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;baseVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_deriveVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deriveVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;修改派生类的访问权限
    &lt;div id=&#34;修改派生类的访问权限&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%bf%ae%e6%94%b9%e6%b4%be%e7%94%9f%e7%b1%bb%e7%9a%84%e8%ae%bf%e9%97%ae%e6%9d%83%e9%99%90&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;

&lt;h4 class=&#34;relative group&#34;&gt;访问修饰符
    &lt;div id=&#34;访问修饰符&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ae%bf%e9%97%ae%e4%bf%ae%e9%a5%b0%e7%ac%a6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;定义派生类的时候，&lt;code&gt;:&lt;/code&gt; 后的访问限定符：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public&lt;/code&gt;: 基类所有访问类型，即为派生类的访问类型。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;protected&lt;/code&gt;: 基类的 &lt;code&gt;public&lt;/code&gt; 在派生类中是 &lt;code&gt;protected&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;private&lt;/code&gt;: 基类的 &lt;code&gt;public&lt;/code&gt; 和 &lt;code&gt;protected&lt;/code&gt; 在派生类中是 &lt;code&gt;private&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基类的 &lt;code&gt;private&lt;/code&gt; 在派生类中默认永远无法访问。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;&lt;code&gt;using&lt;/code&gt;来强制改变单个成员
    &lt;div id=&#34;using来强制改变单个成员&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#using%e6%9d%a5%e5%bc%ba%e5%88%b6%e6%94%b9%e5%8f%98%e5%8d%95%e4%b8%aa%e6%88%90%e5%91%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;可以单独在派生类中修改基类中可访问的成员在派生类的访问权限。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Derive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 假设这两个在 Base 都是公开的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m_var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样就把两个成员在派生类中限制在了 &lt;code&gt;private&lt;/code&gt; 权限，重载函数会全部限制。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;隐藏功能
    &lt;div id=&#34;隐藏功能&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%9a%90%e8%97%8f%e5%8a%9f%e8%83%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;如果基类和派生类存在同名的成员函数，那么派生类会隐藏基类的函数。&lt;/p&gt;
&lt;p&gt;如果向派生类对象传入一个 &lt;code&gt;int&lt;/code&gt;，基类里面的匹配 &lt;code&gt;int&lt;/code&gt;，派生类匹配 &lt;code&gt;double&lt;/code&gt;，还是会优先使用派生类的函数，然后通过数值转化把实参变成 &lt;code&gt;double&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;解决方案是在派生类强制使用 &lt;code&gt;using Base::func&lt;/code&gt; 来使用基类的函数。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;删除功能
    &lt;div id=&#34;删除功能&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%a0%e9%99%a4%e5%8a%9f%e8%83%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;像复制构造函数一样，可以显示删除某些不需要的基类功能，用 &lt;code&gt;= delete&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;但是仍然可以绕过派生类访问基类的功能：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;derived&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;derived&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;虚函数
    &lt;div id=&#34;虚函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%99%9a%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;虚函数是 &lt;code&gt;RTTI&lt;/code&gt;（运行时类型信息）的典型代表。&lt;/p&gt;
&lt;p&gt;在多个派生的类中，如果有签名一致的函数，前面加上 &lt;code&gt;virtual&lt;/code&gt; 关键字，如果有类型为低派生的引用或者指针指向高派生的类，那么使用该指针将会自动调用尽可能高派生的类的函数。&lt;/p&gt;
&lt;p&gt;如果一个派类在其继承链的中只要有一个类的函数是 &lt;code&gt;virtual&lt;/code&gt;，那么其所有相同签名的函数均视为虚函数。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;覆盖
    &lt;div id=&#34;覆盖&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%a6%86%e7%9b%96&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;使用 &lt;code&gt;override&lt;/code&gt; 关键字在派生类中显式的覆盖相同签名的函数，如果无法覆盖会报错，这样避免了签名不一致导致未覆盖还过编译的情况。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;override&lt;/code&gt; 放在成员函数的 &lt;code&gt;const&lt;/code&gt; 后。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;override&lt;/code&gt; 是隐式 &lt;code&gt;virtual&lt;/code&gt; 的，所以只有最底层的基类型需要 &lt;code&gt;virtual&lt;/code&gt; 关键字，其他都可以写 &lt;code&gt;override&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;final&lt;/code&gt; 放在 &lt;code&gt;override&lt;/code&gt; 后，提示这是最后一个覆盖的派生类函数，后续派生的类若再覆盖，则报错。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;协变返回类型
    &lt;div id=&#34;协变返回类型&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8d%8f%e5%8f%98%e8%bf%94%e5%9b%9e%e7%b1%bb%e5%9e%8b&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;当派生类中返回一个 &lt;code&gt;this&lt;/code&gt; 指针的时候，这个指针指向的类型只跟调用它的引用/指针类型有关。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;虚析构函数
    &lt;div id=&#34;虚析构函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%99%9a%e6%9e%90%e6%9e%84%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;如果使用低层的引用/指针指向一个高层的派生类，释放的时候不会正确调用高层的析构函数。此时需要给析构函数添加 &lt;code&gt;virtual&lt;/code&gt; 修饰符。&lt;/p&gt;
&lt;p&gt;不推荐给所有的派生类添加 &lt;code&gt;virtual&lt;/code&gt;，因为虚函数表会造成开销。如果不希望此类被继承，应该在定义类的时候在类名后添加 &lt;code&gt;final&lt;/code&gt; 禁用对此类的继承。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;绑定和调度
    &lt;div id=&#34;绑定和调度&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%91%e5%ae%9a%e5%92%8c%e8%b0%83%e5%ba%a6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;早期绑定/早期调度：在编译的时候就已经确定了调用函数的地址。&lt;/li&gt;
&lt;li&gt;晚期绑定：使用函数指针调用函数&lt;/li&gt;
&lt;li&gt;晚期调度：调用虚函数，通过虚表查询，只有在运行时才知道真正调用的函数。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 class=&#34;relative group&#34;&gt;纯虚函数，纯虚类，虚基类
    &lt;div id=&#34;纯虚函数纯虚类虚基类&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ba%af%e8%99%9a%e5%87%bd%e6%95%b0%e7%ba%af%e8%99%9a%e7%b1%bb%e8%99%9a%e5%9f%ba%e7%b1%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;纯虚函数指的是基类声明了有这个函数，但是实际上无法实例化，只能交由派生类实例化的函数。&lt;/p&gt;
&lt;p&gt;在一个 &lt;code&gt;virtual&lt;/code&gt; 后面加入 &lt;code&gt;= 0&lt;/code&gt; 即可实现，也不需要函数体。&lt;/p&gt;
&lt;p&gt;纯虚类（抽象类）其实相当于一个接口函数，这个类没有成员变量，只有纯虚函数，需要注意必须要有虚析构函数。此类不能被构造，一般在调用的时候，形参为其的引用/指针，并接受其派生类为实参。&lt;/p&gt;
&lt;p&gt;虚基类在继承的 &lt;code&gt;:&lt;/code&gt; 后面加入 &lt;code&gt;virtual&lt;/code&gt;，目的是只有最后一个非虚的派生类创建对象，从而避免菱形继承造成的功能重复。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;切片
    &lt;div id=&#34;切片&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%87%e7%89%87&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;当复制/移动的的目标类型是基类型时，会造成切片，只保留基类实例的部分。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;RTTI
    &lt;div id=&#34;rtti&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#rtti&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;

&lt;h4 class=&#34;relative group&#34;&gt;&lt;code&gt;dynamic_cast&lt;/code&gt;
    &lt;div id=&#34;dynamic_cast&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#dynamic_cast&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;用于向下转换（把一个基类型的指针转换成一个派生类型的指针），造成很大的开销，转换后需要判断是否转换成功。&lt;/p&gt;
&lt;p&gt;当然用 &lt;code&gt;static_cast&lt;/code&gt; 也可以转换，但是不会判断是否是否可以成功转换，访问的时候会造成内存问题。所以不推荐。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;&lt;code&gt;typeid&lt;/code&gt;
    &lt;div id=&#34;typeid&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#typeid&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;获取表达式和类型的类型信息，用于实现 C++ 中的自省。&lt;/p&gt;
&lt;p&gt;重载的运算符 &lt;code&gt;==&lt;/code&gt;，用于比较两个对象是否完全一致。&lt;/p&gt;
&lt;p&gt;成员函数 &lt;code&gt;.name()&lt;/code&gt;，可被打印的、修饰过的编译器名字。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;委派重载函数
    &lt;div id=&#34;委派重载函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a7%94%e6%b4%be%e9%87%8d%e8%bd%bd%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; 不能够被设置成虚函数，因为不是成员函数。但是可以委派给虚函数来打印，只需要把流对象的引用传递过去即可。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;异常处理
    &lt;div id=&#34;异常处理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%bc%82%e5%b8%b8%e5%a4%84%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;经典的 &lt;code&gt;try-catch&lt;/code&gt; 块和 &lt;code&gt;throw&lt;/code&gt; 关键字。&lt;/p&gt;
&lt;p&gt;在主函数里面使用 &lt;code&gt;try&lt;/code&gt; 包裹功能调用函数的时候，函数也可以抛出异常，如果函数本身没有处理，会清理本块的资源，然后依次交由上一级调用栈处理，这个过程叫作栈展开。如果一直到主函数都没有处理，那么就会调用 &lt;code&gt;std::terminate()&lt;/code&gt; 终止程序，此时可能未完成清理。&lt;/p&gt;
&lt;p&gt;因此，建议使用 &lt;code&gt;catch(...)&lt;/code&gt; 在最后捕获所有异常，此时可以保证所有资源都被清理。&lt;/p&gt;
&lt;p&gt;析构函数是隐式 &lt;code&gt;noexcept&lt;/code&gt; 的，因为如果析构函数又抛出异常（二次异常），那么程序将会直接终止。&lt;/p&gt;
&lt;p&gt;异常类和重载不同，对于能同时接受派生类和基类的形参，会优先选择第一个 &lt;code&gt;catch&lt;/code&gt;，所以需要把最匹配的放在前面。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;异常对象的存储机制
    &lt;div id=&#34;异常对象的存储机制&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%bc%82%e5%b8%b8%e5%af%b9%e8%b1%a1%e7%9a%84%e5%ad%98%e5%82%a8%e6%9c%ba%e5%88%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;异常对象会在抛出的时候进行复制，所以这个对象的类必须有复制构造函数，才能正常进行异常流程。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;在 &lt;code&gt;catch&lt;/code&gt; 中抛出异常
    &lt;div id=&#34;在-catch-中抛出异常&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%a8-catch-%e4%b8%ad%e6%8a%9b%e5%87%ba%e5%bc%82%e5%b8%b8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;可以在 &lt;code&gt;catch&lt;/code&gt; 中抛出异常，如果希望再次抛出相同的异常向上处理，应该直接使用 &lt;code&gt;throw;&lt;/code&gt; 而不是显式指定传入的名字，因为按值复制的过程会造成类型切片。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;函数级异常
    &lt;div id=&#34;函数级异常&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%87%bd%e6%95%b0%e7%ba%a7%e5%bc%82%e5%b8%b8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;严格在函数的 &lt;code&gt;()&lt;/code&gt; 后写 &lt;code&gt;try-catch&lt;/code&gt; 块，此过程有隐式重抛异常，最好自己手动指定。&lt;/p&gt;
&lt;p&gt;一般用于构造函数中。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;B&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// note addition of try keyword here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(...)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// note this is at same level of indentation as the function itself
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// Exceptions from member initializer list or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// from constructor body are caught here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cerr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Exception caught&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// throw; // rethrow the existing exception
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;noexcept&lt;/code&gt;
    &lt;div id=&#34;noexcept&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#noexcept&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;没有带 &lt;code&gt;noexcept&lt;/code&gt; 的函数都是潜在的抛出异常的函数。&lt;/p&gt;
&lt;p&gt;要求带有此标记的函数，必须在这个块前完成异常处理，如果超出了这个块，那么整个程序就被强行终止（使用 &lt;code&gt;std::terminate&lt;/code&gt;）&lt;/p&gt;
&lt;p&gt;使用 &lt;code&gt;noexcept&lt;/code&gt; 允许编译器进行深度的优化，因为不需要考虑异常的栈展开机制。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;std::move_if_noexcept&lt;/code&gt;
    &lt;div id=&#34;stdmove_if_noexcept&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdmove_if_noexcept&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;在编译的时候确定移动构造函数是否有 &lt;code&gt;noexcept&lt;/code&gt; 关键字，如果没有，就 &lt;code&gt;fallback&lt;/code&gt; 到复制。&lt;/p&gt;
&lt;p&gt;其实此函数传入的形参是可变的，如果移动构造保证无异常抛出，那么就传入将亡值，使用移动构造函数；如果没有，那么就传入左值，使用复制构造函数。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：移动语义、智能指针与值类别</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-8-move-semantics-smartptr/</link>
      <pubDate>Thu, 30 Oct 2025 14:34:07 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-8-move-semantics-smartptr/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;左右值、&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;、移动语义、智能指针
    &lt;div id=&#34;左右值移动语义智能指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b7%a6%e5%8f%b3%e5%80%bc%e7%a7%bb%e5%8a%a8%e8%af%ad%e4%b9%89%e6%99%ba%e8%83%bd%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;有两个重要概念需要区分：&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;类型 (Type)
    &lt;div id=&#34;类型-type&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b1%bb%e5%9e%8b-type&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;表示一段内存究竟是怎么样的性质。对于一段内存，它内部的结构应该是怎么样被解析的，使用什么样的运算符。&lt;/p&gt;
&lt;p&gt;其实就是一开始的类型系统，包括基本类型的 &lt;code&gt;int&lt;/code&gt;、&lt;code&gt;double&lt;/code&gt;，也可以是标准库中的 &lt;code&gt;std::string&lt;/code&gt;，用户在 &lt;code&gt;class&lt;/code&gt; 定义类型。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;值类别 (Value Category)
    &lt;div id=&#34;值类别-value-category&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%80%bc%e7%b1%bb%e5%88%ab-value-category&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;在移动语义后完善的概念，重点关注此表达式本身的性质，具有什么身份，是否可以被移动。&lt;/p&gt;
&lt;p&gt;在 C++98，只有&lt;strong&gt;左值&lt;/strong&gt;和&lt;strong&gt;右值&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;但是在 C++11，我们引入了移动语义，出现了一个&lt;strong&gt;将亡值&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;将亡值有身份可以取地址，但是马上被移动也就消失了，所以我们扩大了左值的定义，认为他是&lt;strong&gt;广义左值&lt;/strong&gt;；&lt;/p&gt;
&lt;p&gt;同时，因为他即将消失，所以认为是右值，那么就把以前的右值定义为&lt;strong&gt;纯右值&lt;/strong&gt;，这样五种值类别就出来了。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;/&lt;code&gt;&amp;amp;&lt;/code&gt; 作为函数形参
    &lt;div id=&#34;-作为函数形参&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#-%e4%bd%9c%e4%b8%ba%e5%87%bd%e6%95%b0%e5%bd%a2%e5%8f%82&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;考虑下面这个函数：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;给出两个 &lt;code&gt;fun&lt;/code&gt; 的函数声明：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;事实上，只有第二个能够匹配传入的参数，而不是第一个。&lt;/p&gt;
&lt;p&gt;在没有引用的时候，我们的函数形参其实是匹配对象的类型的，因为只有确定了类型，函数内部才知道这个对象使用哪一种操作符，如何解释这一段内存。&lt;/p&gt;
&lt;p&gt;引入引用之后，带 &lt;code&gt;&amp;amp;&lt;/code&gt; 的参数会解释这个对象如何绑定到实参：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;左值引用&lt;/strong&gt;：只能绑定到左值。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常量左值引用&lt;/strong&gt;：能绑定到左值和右值，如果&lt;strong&gt;直接&lt;/strong&gt;绑定到右值，会延长该对象的生命周期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;右值引用&lt;/strong&gt;：绑定到右值时，在函数内部转换成一个左值；绑定到左值时，是一个左值引用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是需要注意一点，虽然 &lt;code&gt;ref&lt;/code&gt; 是一个 &lt;code&gt;int&amp;amp;&amp;amp;&lt;/code&gt; 类型的对象，但是他的值类别其实是一个左值，所以形参可以是一个 (常量) 左值引用。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 在模板参数的使用
    &lt;div id=&#34;-在模板参数的使用&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#-%e5%9c%a8%e6%a8%a1%e6%9d%bf%e5%8f%82%e6%95%b0%e7%9a%84%e4%bd%bf%e7%94%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;仅在模板以及泛型中，&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 才有引用折叠作用，常用于完美转发。&lt;/p&gt;
&lt;p&gt;最常见的在于这样一个泛型函数：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;arg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;传入左值的时候，会被折叠成 &lt;code&gt;T&amp;amp;&lt;/code&gt;，而传入右值的时候，保留 &lt;code&gt;T&amp;amp;&amp;amp;&lt;/code&gt; 的类型，&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;非常智能，自动判断左右值。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;实现移动
    &lt;div id=&#34;实现移动&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%9e%e7%8e%b0%e7%a7%bb%e5%8a%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;std::move()&lt;/code&gt; 返回的值是一个将亡值 (xvalue)，至于如何把这个值移动，是类的移动构造函数/移动赋值运算符实现的。&lt;/p&gt;
&lt;p&gt;所以如果手动编写的移动构造函数/移动赋值运算符，需要注意：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;加上 &lt;code&gt;noexcept&lt;/code&gt; 关键字，避免抛出异常（要么成功，要么终止，避免移动一半），避免回退到复制。&lt;/li&gt;
&lt;li&gt;手动把地址给到目标，然后把原来的指针指向空指针。&lt;/li&gt;
&lt;li&gt;对于运算符，可以加上判断一下不是自己给自己，如果是就返回 &lt;code&gt;*this&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;至于源对象如何释放，是取决它本身的生命周期的。此时我们已经完成了所有权的转移。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;智能指针
    &lt;div id=&#34;智能指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%99%ba%e8%83%bd%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;

&lt;h4 class=&#34;relative group&#34;&gt;&lt;code&gt;unique_ptr&lt;/code&gt;
    &lt;div id=&#34;unique_ptr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#unique_ptr&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;这个指针指向的堆内存必须是它独占的，如果使用移动语义来赋值的话，会自动把上一个指针置空。&lt;/p&gt;
&lt;p&gt;不要用一个裸指针来初始化一个智能指针，虽然语法上成立，但是语义上会破坏 &lt;code&gt;unique&lt;/code&gt; 的独占性，仍然会发生双重释放的问题。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;使用 &lt;code&gt;make_unique&lt;/code&gt; 将一个纯右值的对象变成独占的指针，不用手动 &lt;code&gt;new&lt;/code&gt; 故比较推荐。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;make_unique&lt;/code&gt; 其实是一个函数，为一个纯右值返回一个独占指针，所以返回值一定会有一个指针接收，一般用 &lt;code&gt;auto&lt;/code&gt; 配合效果很好：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;make_unique&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fraction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fraction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;如果要求传入一个类型的裸指针，但是手上只有智能指针，可以使用 &lt;code&gt;.get()&lt;/code&gt; 来得到一个底层中使用的裸指针的副本。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;&lt;code&gt;shared_ptr&lt;/code&gt; 和 &lt;code&gt;weak_ptr&lt;/code&gt;
    &lt;div id=&#34;shared_ptr-和-weak_ptr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#shared_ptr-%e5%92%8c-weak_ptr&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;共享指针允许多个指针同时指向一块内存，同时其内部会保存指向这段内存的计数。当最后一个共享指针销毁的时候，内存将会被自动释放。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;不过 &lt;code&gt;shared_ptr&lt;/code&gt; 会导致两个共享指针相互依赖的问题，这样在释放的时候认为是互相依赖使得最终内存无法释放导致内存泄漏。&lt;/p&gt;
&lt;p&gt;最典型的例子就是，在一个类中有 &lt;code&gt;shared_ptr&lt;/code&gt; 的成员变量，然后两个实例化的对象的共享指针指向对方，同时具有相同的生命周期，这样释放的时候互相认为对方存在，从而都不释放内存。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;因此，&lt;code&gt;weak_ptr&lt;/code&gt; 出现了。弱指针不增加引用计数，因此可以很好的解决上面的问题。&lt;/p&gt;
&lt;p&gt;弱指针其实有点像 &lt;code&gt;string_view&lt;/code&gt;，他们都只是一个视图（观察者）而已。&lt;/p&gt;
&lt;p&gt;使用弱指针：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.expired()&lt;/code&gt; 可以检测弱指针是否指向无效的内存。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.lock()&lt;/code&gt; 锁定指向的内容，把引用计数 +1，同时返回一个 &lt;code&gt;shared_ptr&lt;/code&gt;；如果已过期，那么会返回 &lt;code&gt;nullptr&lt;/code&gt;（这样甚至不需要 &lt;code&gt;std::optional&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 class=&#34;relative group&#34;&gt;关系
    &lt;div id=&#34;关系&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%85%b3%e7%b3%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;unique_ptr&lt;/code&gt; 可以转化为 &lt;code&gt;shared_ptr&lt;/code&gt;，反之不能转化。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;unique_ptr&lt;/code&gt; 只能移动不能拷贝，&lt;code&gt;shared_ptr&lt;/code&gt; 和 &lt;code&gt;weak_ptr&lt;/code&gt; 可以拷贝。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;shared_ptr&lt;/code&gt; 可以被 &lt;code&gt;weak_ptr&lt;/code&gt; 创建一个视图。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;weak_ptr&lt;/code&gt; 的成员函数 &lt;code&gt;.lock()&lt;/code&gt; 有效时会返回一个 &lt;code&gt;shared_ptr&lt;/code&gt;，否则会返回一个 &lt;code&gt;nullptr&lt;/code&gt;。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;组合、聚合和关联
    &lt;div id=&#34;组合聚合和关联&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%84%e5%90%88%e8%81%9a%e5%90%88%e5%92%8c%e5%85%b3%e8%81%94&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;属性 (Property)&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;组合 (Composition)&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;聚合 (Aggregation)&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;关联 (Association)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;关系类型&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;整体/部分&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;整体/部分&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;其他不相关&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;部分可属于多个整体&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;否&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;是&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;是&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;部分的存在由整体管理&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;是&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;否&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;否&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;方向性&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;单向&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;单向&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;单向或双向&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;关系动词&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;是&amp;hellip;的一部分 (Part-of)&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;拥有 (Has-a)&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;使用 (Uses-a)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;**方式&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;类成员&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;引用 (数组)&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;引用 (数组)&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 class=&#34;relative group&#34;&gt;初始化列表 &lt;code&gt;initializer_list&lt;/code&gt;
    &lt;div id=&#34;初始化列表-initializer_list&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%9d%e5%a7%8b%e5%8c%96%e5%88%97%e8%a1%a8-initializer_list&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;如果想要让自己的类使用一个初始化列表来初始化，需要手动添加一个重载的构造函数：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]}{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;initializer_list&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// 用委托构造函数来创建一个
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;begin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 3/5/0 法则的其他函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：Lambda、运算符重载与闭包</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-7-lambda-operator-overload/</link>
      <pubDate>Wed, 22 Oct 2025 16:29:09 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-7-lambda-operator-overload/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;命令行参数
    &lt;div id=&#34;命令行参数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%91%bd%e4%bb%a4%e8%a1%8c%e5%8f%82%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;早就知道在 &lt;code&gt;c&lt;/code&gt; 中是可以在 &lt;code&gt;main&lt;/code&gt; 中获取从命令行传入的参数的。但是对于解析是一窍不通，这里简单说一下如何获取整形。&lt;/p&gt;
&lt;p&gt;不过，这些方法都仅仅适用于简单的字符串处理，而一个简单的带参 &lt;code&gt;cli&lt;/code&gt; 程序，基本都要求参数能够无视顺序，可选参数，这些统统都不能实现&amp;hellip;&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;std::stringstream&lt;/code&gt;
    &lt;div id=&#34;stdstringstream&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdstringstream&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;这个函数用于把字符串转换成流，然后再把流输出到整形。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stringstream&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arcv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;std::stoi
    &lt;div id=&#34;stdstoi&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdstoi&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;这个就是现代 C++ 的方法了。&lt;/p&gt;
&lt;p&gt;直接转换就行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 class=&#34;relative group&#34;&gt;lambda 表达式
    &lt;div id=&#34;lambda-表达式&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#lambda-%e8%a1%a8%e8%be%be%e5%bc%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;lambda 表达式看起来像这样子：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;capture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parameter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参数列表可以省略，返回值也可以省略，会自动推断。&lt;/p&gt;
&lt;p&gt;所以说，最简的 &lt;code&gt;lambda&lt;/code&gt; 表达式：&lt;code&gt;[]{}&lt;/code&gt;。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;捕获
    &lt;div id=&#34;捕获&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8d%95%e8%8e%b7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;对于以下变量来说，不需要捕获也可使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全局变量，静态局部变量，线程局部变量&lt;/li&gt;
&lt;li&gt;常量表达式（包括被编译器视为常量表达式的变量）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;捕获语法是 &lt;code&gt;lambda&lt;/code&gt; 表达式中一个不可缺少的部分，词法分析就是通过 &lt;code&gt;[]&lt;/code&gt; 来发现这是一个表达式的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;lambda&lt;/code&gt; 表达式不和 &lt;code&gt;{}&lt;/code&gt; 一样，不能访问上级大括号中的局部变量。它只能访问静态和全局的变量，以及 &lt;code&gt;constexpr&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而捕获其实就是把原来应该能让 &lt;code&gt;lambda&lt;/code&gt; 能够使用的局部变量让它使用。&lt;/p&gt;
&lt;p&gt;捕获的时候可以声明新变量的，在 &lt;code&gt;[]&lt;/code&gt; 内，可以使用当前块内能访问的变量来参与运算。&lt;/p&gt;
&lt;p&gt;捕获有两种类型：默认捕获和单个捕获。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;按对象捕获
    &lt;div id=&#34;按对象捕获&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8c%89%e5%af%b9%e8%b1%a1%e6%8d%95%e8%8e%b7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;假设有变量 &lt;code&gt;a&lt;/code&gt; &lt;code&gt;b&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;传值：&lt;code&gt;[a,b]&lt;/code&gt;。默认传入变量的&lt;strong&gt;常量&lt;/strong&gt;值，如果需要修改，需要在大括号前加上 &lt;code&gt;mutable&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;传引用：&lt;code&gt;[&amp;amp;a,&amp;amp;b]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class=&#34;relative group&#34;&gt;默认捕获
    &lt;div id=&#34;默认捕获&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%bb%98%e8%ae%a4%e6%8d%95%e8%8e%b7&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;默认捕获会捕获 &lt;code&gt;lambda&lt;/code&gt; 中提到的所有变量。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[=]&lt;/code&gt;：传入值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[&amp;amp;]&lt;/code&gt;：传入引用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不允许同时使用默认捕获和按对象的捕获。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;创建闭包
    &lt;div id=&#34;创建闭包&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%9b%e5%bb%ba%e9%97%ad%e5%8c%85&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;提到闭包这个词，就不得不提函数式编程了。简单来说，函数是“一等公民”，就像我们传统的命令式编程的变量（对象）一样，可以作为参数传递，可以被返回，可以运行时创建等等。&lt;/p&gt;
&lt;p&gt;那么闭包就是保存了当前上下文中某些状态的函数。&lt;/p&gt;
&lt;p&gt;在 C++ 中，想实现一个闭包，还是得定义一个普通函数（虽然说跟一般的匿名函数印象不太一样）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;factor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;factor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;factor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply_3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply_4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply_3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multiply_4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;multiply_3&lt;/code&gt; 和 &lt;code&gt;multiply_4&lt;/code&gt; 就是一个闭包。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;实现一个简单的函数
    &lt;div id=&#34;实现一个简单的函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%9e%e7%8e%b0%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;

&lt;h4 class=&#34;relative group&#34;&gt;&lt;code&gt;lambda&lt;/code&gt; 表达式可以作为 &lt;code&gt;lambda&lt;/code&gt; 类型的变量存储。
    &lt;div id=&#34;lambda-表达式可以作为-lambda-类型的变量存储&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#lambda-%e8%a1%a8%e8%be%be%e5%bc%8f%e5%8f%af%e4%bb%a5%e4%bd%9c%e4%b8%ba-lambda-%e7%b1%bb%e5%9e%8b%e7%9a%84%e5%8f%98%e9%87%8f%e5%ad%98%e5%82%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{[](&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 class=&#34;relative group&#34;&gt;也可以声明的时候就调用：
    &lt;div id=&#34;也可以声明的时候就调用&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b9%9f%e5%8f%af%e4%bb%a5%e5%a3%b0%e6%98%8e%e7%9a%84%e6%97%b6%e5%80%99%e5%b0%b1%e8%b0%83%e7%94%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[]()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Hello world!&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 前一个括号是形参列表，后一个括号表示调用函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;值得提的一点是，这其实不是真正的函数，实际上只是重载了 &lt;code&gt;()&lt;/code&gt; 实现像函数一样的调用。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;在算法库的应用
    &lt;div id=&#34;在算法库的应用&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%a8%e7%ae%97%e6%b3%95%e5%ba%93%e7%9a%84%e5%ba%94%e7%94%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;前面在 &lt;code&gt;&amp;lt;algorithm&amp;gt;&lt;/code&gt; 中，最后一个参数是比较函数的地址，其实我们可以直接在这里写 &lt;code&gt;lambda&lt;/code&gt; 函数。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;lambda 推断
    &lt;div id=&#34;lambda-推断&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#lambda-%e6%8e%a8%e6%96%ad&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;对于实参推断（给出 &lt;code&gt;(auto a, auto b)&lt;/code&gt; 的情况，只要函数体里面的能匹配，那么没有问题，因为编译器会自动生成重载的 &lt;code&gt;lambda&lt;/code&gt; 表达式。&lt;/p&gt;
&lt;p&gt;对于返回值，要求所有返回的地方一致才能推断，否则，请使用 &lt;code&gt;-&amp;gt;&lt;/code&gt; 手动指定返回值类型。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;带捕获的 &lt;code&gt;lambda&lt;/code&gt; 拷贝
    &lt;div id=&#34;带捕获的-lambda-拷贝&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b8%a6%e6%8d%95%e8%8e%b7%e7%9a%84-lambda-%e6%8b%b7%e8%b4%9d&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;如果对带捕获的 &lt;code&gt;lambda&lt;/code&gt; 表达式操作的时候，目标的类型是 &lt;code&gt;std::function&lt;/code&gt;，那么会发生隐式类型转换，将 &lt;code&gt;lambda&lt;/code&gt; 闭包进行深拷贝，使得多次使用 &lt;code&gt;std::function&lt;/code&gt; 构造的多个对象出现独立的拥有原始闭包状态的副本。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;lambda&lt;/code&gt; 构造的时候使用了 &lt;code&gt;mutable&lt;/code&gt; 的值捕获，那么每次捕获的变量都是原始的捕获值。&lt;/p&gt;
&lt;p&gt;解决方法是使用 &lt;code&gt;std::ref&lt;/code&gt; 来包装 &lt;code&gt;lambda&lt;/code&gt; 表达式。对于传入参数不一致的情况，它会返回一个 &lt;code&gt;std::reference_wrapper&lt;/code&gt;  对象，保证内部存储的是对原始 &lt;code&gt;lambda&lt;/code&gt; 对象的引用，从而保证每次调用的是同一个 &lt;code&gt;lambda&lt;/code&gt; 表达式对象。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;运算符重载
    &lt;div id=&#34;运算符重载&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%90%e7%ae%97%e7%ac%a6%e9%87%8d%e8%bd%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;有三种办法重载：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;友元函数&lt;/strong&gt;：如果想要重载操作数是类对象的运算符，为了获取类内成员的访问权限，可以把此重载函数以友元的形式声明在类内。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;普通函数&lt;/strong&gt;：同时可以使用 &lt;code&gt;getter&lt;/code&gt; 和 &lt;code&gt;setter&lt;/code&gt; 来避免直接访问内部的成员变量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;类成员函数&lt;/strong&gt;：仅适用于左侧操作数是类成员的情况，此时右操作数就作为参数。&lt;/p&gt;
&lt;p&gt;一些选择建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重载赋值、下标 (&lt;code&gt;[]&lt;/code&gt;)、函数调用、成员选择 (&lt;code&gt;-&amp;gt;&lt;/code&gt;) -&amp;gt; 类成员函数&lt;/li&gt;
&lt;li&gt;重载一元运算符 -&amp;gt; 类成员函数&lt;/li&gt;
&lt;li&gt;不修改左操作数 -&amp;gt; 普通/友元函数&lt;/li&gt;
&lt;li&gt;左操作数是内置类型无法修改 -&amp;gt; 普通/友元函数&lt;/li&gt;
&lt;li&gt;左操作数可以修改 -&amp;gt; 类成员函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重载函数一般返回左侧的对象&lt;strong&gt;的引用&lt;/strong&gt;（以便可以连续用 &lt;code&gt;.&lt;/code&gt; 调用）或者返回一个同类型的对象（用于连续使用重载运算符比如 &lt;code&gt;+=&lt;/code&gt;）。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;重载一元+/-
    &lt;div id=&#34;重载一元-&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%87%8d%e8%bd%bd%e4%b8%80%e5%85%83-&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;由于一元的 &lt;code&gt;+/-&lt;/code&gt; 是类成员函数，而且没有参数，所以不会和二元的混淆。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;重载自增/减
    &lt;div id=&#34;重载自增减&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%87%8d%e8%bd%bd%e8%87%aa%e5%a2%9e%e5%87%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;前自增/减参数列表没有参数，而后自增/减有一个 &lt;code&gt;int&lt;/code&gt; 用于占位，从而将两者区分。&lt;/p&gt;
&lt;p&gt;由于后自增/减要返回原来的值，所以需要一个临时变量用于返回，相比前自增/减多了开销，更倾向使用前自增/减。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;下标访问重载
    &lt;div id=&#34;下标访问重载&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%8b%e6%a0%87%e8%ae%bf%e9%97%ae%e9%87%8d%e8%bd%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;下标访问的重载返回值一般使用 &lt;code&gt;auto&amp;amp;&lt;/code&gt;，从而作为左值被修改。&lt;/p&gt;
&lt;p&gt;在 C++23 之前，如果定义类的时候使用 &lt;code&gt;const&lt;/code&gt;，那么就需要添加一个成员重载函数：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;operator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个函数被常量对象优先使用，被非常量对象次优先使用。&lt;/p&gt;
&lt;p&gt;在 C++23，用右值引用解决此问题。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;飞船运算符
    &lt;div id=&#34;飞船运算符&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%a3%9e%e8%88%b9%e8%bf%90%e7%ae%97%e7%ac%a6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;外来语言的符号，用于比较两个数大小关系。&lt;/p&gt;
&lt;p&gt;返回下面类型：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;strong_ordering&lt;/code&gt;&lt;/strong&gt;: 有&lt;code&gt;equivalent&lt;/code&gt;、&lt;code&gt;equal&lt;/code&gt;、&lt;code&gt;greater&lt;/code&gt; 和 &lt;code&gt;less&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;weak_ordering&lt;/code&gt;&lt;/strong&gt;: 比 &lt;code&gt;strong&lt;/code&gt; 少了相等，因为是弱，只有等效。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;partial_ordering&lt;/code&gt;&lt;/strong&gt;: 相比 &lt;code&gt;weak&lt;/code&gt; 多了 &lt;code&gt;unordered&lt;/code&gt;，用于表示无法比较的情况。&lt;/p&gt;
&lt;p&gt;从上往下可以隐式转换。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;类型转换重载
    &lt;div id=&#34;类型转换重载&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b1%bb%e5%9e%8b%e8%bd%ac%e6%8d%a2%e9%87%8d%e8%bd%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;类型转换重载也是 &lt;code&gt;operator&lt;/code&gt; 操作符，不过重载的目标其实有点像 C 的强制转换：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;operator&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// conversion
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;intType_obj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;无须返回值，也无须参数，因为显而易见的返回目标类型，传入的是这个类对象，这也必须是一个类成员函数。&lt;/p&gt;
&lt;p&gt;建议加上 &lt;code&gt;explicit&lt;/code&gt; 关键字，因为我们不希望隐式转换带来的不确定性。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如何平衡类型转换重载和转换构造函数？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;假设要把 A 转换成 B：&lt;/p&gt;
&lt;p&gt;A 可改，B 不可改。那么就定义一个类型转换的重载。&lt;/p&gt;
&lt;p&gt;A 不可改，B 可改。那么就定义一个参数只含 A 的转换构造函数，让 B 去接收 A。&lt;/p&gt;
&lt;p&gt;A、B 都不可改。那么定义一个普通函数实现转换吧。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;复制运算符重载
    &lt;div id=&#34;复制运算符重载&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a4%8d%e5%88%b6%e8%bf%90%e7%ae%97%e7%ac%a6%e9%87%8d%e8%bd%bd&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;在动态分配内存中，有时为了避免自己赋值给自己，用一个 &lt;code&gt;if&lt;/code&gt; 来设置保护防止出现空指针问题。&lt;/p&gt;
&lt;p&gt;在三/五/零原则中，如果不带指针，那么应该不应该定义这个复制运算符重载。（其他：析构、复制构造，移动运算符，移动构造函数）&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：容器、迭代器与算法库</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-6-containers-iterators-algorithms/</link>
      <pubDate>Mon, 13 Oct 2025 08:25:04 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-6-containers-iterators-algorithms/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;std::vector
    &lt;div id=&#34;stdvector&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdvector&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;此向量非彼向量。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;对于字符串
    &lt;div id=&#34;对于字符串&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%af%b9%e4%ba%8e%e5%ad%97%e7%ac%a6%e4%b8%b2&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;推荐使用&lt;code&gt;string_view&lt;/code&gt;配合 C 风格的字符串，这样效率最高，只发生一次堆内存分配。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;names&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Alex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Betty&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Caroline&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Dave&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Emily&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Fred&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Greg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Holly&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;列表初始化器
    &lt;div id=&#34;列表初始化器&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%97%e8%a1%a8%e5%88%9d%e5%a7%8b%e5%8c%96%e5%99%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;std::vector vec(3)&lt;/code&gt;会初始化一个全 0，长度为 3 的向量；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::vecotr vec(2,3)&lt;/code&gt;会初始化一个长度 2，值都为 3 的向量。&lt;/li&gt;
&lt;li&gt;但是&lt;code&gt;std::vector vec({3})&lt;/code&gt;会初始化一个长度 1 值为 3 的向量。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为给出单参数的时候，会优先调用列表初始化器，这个初始化器的行为是初始化长度为参数的向量。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;下标
    &lt;div id=&#34;下标&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%8b%e6%a0%87&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;当时设计让&lt;code&gt;size_t&lt;/code&gt;是一个无符号的整数，从现在看来是一个错误，因为下标访问最容易导致环绕，最好的办法是不使用下标访问而是迭代器，次选是使用 C 风格的访问&lt;code&gt;.data()&lt;/code&gt;。然后全部使用有符号整数。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;for-each
    &lt;div id=&#34;for-each&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#for-each&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;推荐使用这些：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;修改元素副本&lt;/strong&gt;：&lt;code&gt;auto&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修改原始元素&lt;/strong&gt;：&lt;code&gt;auto&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;只需要查看&lt;/strong&gt;：&lt;code&gt;const auto&amp;amp;&lt;/code&gt;（大多数情况）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;反向查看：使用&lt;code&gt;std::view::reverse()&lt;/code&gt;&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;容量和长度
    &lt;div id=&#34;容量和长度&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%b9%e9%87%8f%e5%92%8c%e9%95%bf%e5%ba%a6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;容量是分配给向量的内存，长度是实际使用的部分。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pop&lt;/code&gt;的时候长度减少容量不变；&lt;code&gt;push&lt;/code&gt;时如果遇到容量瓶颈，会自动复制扩容（2/1.5）倍。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;resize&lt;/code&gt;成员函数会同时改变容量和长度，&lt;code&gt;reserve&lt;/code&gt;只改变容量。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;emplace_back&lt;/code&gt;会显示调用构造函数，直接在堆上预留的内存构建对象，如果是是临时对象，那么要注意如果有&lt;code&gt;explicit&lt;/code&gt;那么不能执行隐式转换。而&lt;code&gt;push_back&lt;/code&gt;会发生一次拷贝。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;make_unique&lt;/code&gt; 下，始终会产生一次拷贝，此时两者表现一致。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;std::array
    &lt;div id=&#34;stdarray&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdarray&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;array&lt;/code&gt; 大部分功能都与 &lt;code&gt;constexpr&lt;/code&gt; 兼容。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;constexpr&lt;/code&gt; 表达式执行的从 &lt;code&gt;unsign&lt;/code&gt; 到 &lt;code&gt;sign&lt;/code&gt; 的转换是允许的，因为编译器对此信任程度很高。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;.at()、[]和 std::get()
    &lt;div id=&#34;at和-stdget&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#at%e5%92%8c-stdget&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.at()&lt;/code&gt;&lt;/strong&gt;: 运行时边界检查。(C++17 后编译时检查)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;std::get&amp;lt;index&amp;gt;(arr)&lt;/code&gt;&lt;/strong&gt;: 编译时边界检查。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/strong&gt;: 不进行边界检查，C++11 后可为 &lt;code&gt;constexpr&lt;/code&gt; 。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于现代 C++ 来说， &lt;code&gt;.at&lt;/code&gt; 是更安全的选择。&lt;/p&gt;
&lt;p&gt;因为会在越界访问的时候抛出异常。而 &lt;code&gt;[]&lt;/code&gt; 不会进行越界检查。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;用模板创建数组
    &lt;div id=&#34;用模板创建数组&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%94%a8%e6%a8%a1%e6%9d%bf%e5%88%9b%e5%bb%ba%e6%95%b0%e7%bb%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;passByRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;arr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;static_assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;由于模板参数是编译时常量，所以可以用 &lt;code&gt;static_assert&lt;/code&gt; ，同时，更加推荐把这两句用 &lt;code&gt;std::get&amp;lt;N&amp;gt;(arr)&lt;/code&gt; 替代。&lt;/p&gt;
&lt;p&gt;在 C++20，可以把 &lt;code&gt;size_t&lt;/code&gt; 替换成 &lt;code&gt;auto&lt;/code&gt; 。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;在函数内返回 array
    &lt;div id=&#34;在函数内返回-array&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%9c%a8%e5%87%bd%e6%95%b0%e5%86%85%e8%bf%94%e5%9b%9e-array&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;由于 &lt;code&gt;array&lt;/code&gt; 是在栈上分配的，那么一般来说会执行返回值优化，但是移动语义就没有意义（因为不是在堆上分配的就不能仅转移指针）。如果在 C++17 之前为了避免不确定性，那用 &lt;code&gt;vector&lt;/code&gt; ？但是怎么感觉开销在堆上更大了说&amp;hellip;&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;初始化聚合数组
    &lt;div id=&#34;初始化聚合数组&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%9d%e5%a7%8b%e5%8c%96%e8%81%9a%e5%90%88%e6%95%b0%e7%bb%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;列表初始化，但是兼容 C 带来的技术债。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;constexpr&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;House&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;houses&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 1. 初始化 std::array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 2. 初始化底层 C 风格数组 (元素列表)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 3. 初始化第一个 House 结构体
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 3. 初始化第二个 House 结构体
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 3. 初始化第三个 House 结构体
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此时不使用 CTAD，但是必须手动指定模板参数，或者，指定每一个元素的类型，此时可以 CTAD：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;constexpr&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;houses&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 1. 初始化 std::array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Horse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 3. 初始化第一个 House 结构体
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Horse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 3. 初始化第二个 House 结构体
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Horse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// 3. 初始化第三个 House 结构体
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;reference_wrapper
    &lt;div id=&#34;reference_wrapper&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#reference_wrapper&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;容器中不能给模板传入 &lt;code&gt;int&amp;amp;&lt;/code&gt; 但是可以传入一个 &lt;code&gt;std::reference_wrapper&amp;lt;int&amp;gt;&lt;/code&gt; 起到同样的作用，或者直接用 &lt;code&gt;std::ref()&lt;/code&gt; &lt;code&gt;std::cref()&lt;/code&gt; 直接把变量转换成引用。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;迭代器
    &lt;div id=&#34;迭代器&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bf%ad%e4%bb%a3%e5%99%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;迭代器一般使用 &lt;code&gt;!=end&lt;/code&gt; 来判断是否到达末尾，因为不是所有迭代器都可以比较。&lt;/p&gt;
&lt;p&gt;其本身是一个指针，指向当前的容器元素。&lt;/p&gt;
&lt;p&gt;写的 &lt;code&gt;range based for&lt;/code&gt; 实际上就是迭代器的语法糖。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;algorithems 库
    &lt;div id=&#34;algorithems-库&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#algorithems-%e5%ba%93&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;这是一个算法库，用于偷懒（不是&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;补充知识
    &lt;div id=&#34;补充知识&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%a1%a5%e5%85%85%e7%9f%a5%e8%af%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;二元谓词：就是接受两个参数，返回一个布尔值的函数。&lt;/p&gt;
&lt;p&gt;在算法库中，二元谓词都需要弱序，即非自反性 (自己不能小于自己)，非对称性 (a 小于 b，那么 b 不能小于 a)，传递性。&lt;/p&gt;
&lt;p&gt;对于 &lt;code&gt;Comp&lt;/code&gt; 这个类型，我们假设前一个参数是 &lt;code&gt;a&lt;/code&gt;，后一个是 &lt;code&gt;b&lt;/code&gt;。那么有：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;对 &lt;code&gt;a&lt;/code&gt; 和 &lt;code&gt;b&lt;/code&gt; 进行某种运算，如果希望最后算法需要保持 &lt;code&gt;a&lt;/code&gt; 排在 &lt;code&gt;b&lt;/code&gt; 的前面，那么就返回 &lt;code&gt;true&lt;/code&gt;；如果算法认为 &lt;code&gt;a&lt;/code&gt; &lt;strong&gt;不&lt;/strong&gt;应该排在 &lt;code&gt;b&lt;/code&gt; 的前面，那么就返回 &lt;code&gt;false&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最简单的办法是，假设已经按照一个顺序排列，然后取出前两个元素为 &lt;code&gt;a&lt;/code&gt; 和 &lt;code&gt;b&lt;/code&gt;，将他们放入表达式，如果返回 &lt;code&gt;true&lt;/code&gt;，那么这就是你要的顺序，为 &lt;code&gt;false&lt;/code&gt; 则是另外一个顺序。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;std::sort
    &lt;div id=&#34;stdsort&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdsort&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;sort 有第三个参数，传入一个二元谓词，在 &lt;code&gt;cppreference&lt;/code&gt; 中类型为 &lt;code&gt;Comp&lt;/code&gt; ,如果是一个函数的话，只需要传地址所以不用 &lt;code&gt;()&lt;/code&gt;。这个函数必须严格弱序的。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;std::for_each
    &lt;div id=&#34;stdfor_each&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdfor_each&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;foreach&lt;/code&gt; 可以用于方便的遍历可以迭代的容器。给定开始和结束的迭代器，和要调用的函数地址（这个函数只能传入一个参数，可用 &lt;code&gt;auto&lt;/code&gt; ），就可以自动迭代。&lt;/p&gt;
&lt;p&gt;同时和 &lt;code&gt;std::next&lt;/code&gt; 配合使用，可以跳过一部分迭代器，获得很高的灵活性。这时候就有了比基于范围的 &lt;code&gt;for&lt;/code&gt; 循环更加灵活。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;ranges (C++20)
    &lt;div id=&#34;ranges-c20&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#ranges-c20&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;从 C++20 开始，很多算法添加了对应的重载，直接传入容器的地址就可以实现操作，即 &lt;code&gt;std::ranges::for_each(arr)&lt;/code&gt;。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;函数指针
    &lt;div id=&#34;函数指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%87%bd%e6%95%b0%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;C 的函数指针如果不用 &lt;code&gt;typedef&lt;/code&gt;将会非常复杂，而 C++ 提供了一个模板，以一个传入 &lt;code&gt;int, int&lt;/code&gt; 返回 &lt;code&gt;int&lt;/code&gt; 的函数指针为例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&amp;lt;functional&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// some implementation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：类、构造函数与成员初始化</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-5-class-ctor-init/</link>
      <pubDate>Mon, 29 Sep 2025 08:25:14 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-5-class-ctor-init/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;枚举
    &lt;div id=&#34;枚举&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%9e%9a%e4%b8%be&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;枚举实现了内容与整形相关联的数据结构，是隐式的编译时常量。&lt;/p&gt;
&lt;p&gt;枚举类型，枚举符和枚举变量。&lt;/p&gt;
&lt;p&gt;枚举符会放入当前命名空间和其本身的命名空间中，如果是全局的枚举 (unscoped),那么可以直接使用。&lt;/p&gt;
&lt;p&gt;对枚举变量空初始化会使得枚举符是 0，所以推荐把第一个枚举符设置成未知/无效。&lt;/p&gt;
&lt;p&gt;枚举类用&lt;code&gt;enum class Name{};&lt;/code&gt;定义，只能在其本身的作用域使用，无法被隐式转换成整数，在安全性上更优。&lt;/p&gt;
&lt;p&gt;可以在需要的使用&lt;code&gt;using enum Name;&lt;/code&gt;来简化使用 (C++20)。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;结构体
    &lt;div id=&#34;结构体&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%93%e6%9e%84%e4%bd%93&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;对其中某些参数进行初始化：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Worker&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Worker&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;John&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//部分列表初始化，age 初始化为 0，clangd 有 bug 会警告
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Worker&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;John&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;John&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//这样可以占位，一样使得 age 初始化为 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;结构体模板
    &lt;div id=&#34;结构体模板&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%bb%93%e6%9e%84%e4%bd%93%e6%a8%a1%e6%9d%bf&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;结构体当然也可以传入模板参数，不过在 C++20 更加完善，如果使用 C++17，可能需要手动指定推断：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Pair&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Here&amp;#39;s a deduction guide for our Pair (needed in C++17 only)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Pair objects initialized with arguments of type T and T should deduce to Pair&amp;lt;T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// explicitly specify class template Pair&amp;lt;int&amp;gt; (C++11 onward)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;// CTAD used to deduce Pair&amp;lt;int&amp;gt; from the initializers (C++17)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以为类型模板起别名：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Coord&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Coord is an alias for Pair&amp;lt;T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 class=&#34;relative group&#34;&gt;类
    &lt;div id=&#34;类&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b1%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;类的成员变量，成员函数是隐式内联的，所以放在头文件中被多个源文件引用的时候，不违反 ODR 原则。&lt;/p&gt;
&lt;p&gt;在类中，不强制声明语句位于使用之前，只要他们都在同一个类中即可。&lt;/p&gt;
&lt;p&gt;调用常量类对象内部的函数，要将此成员函数声明为&lt;code&gt;const&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;struct&lt;/code&gt;和&lt;code&gt;class&lt;/code&gt;仅有的差异：&lt;code&gt;struct&lt;/code&gt;默认使用&lt;code&gt;public:&lt;/code&gt;，而&lt;code&gt;class&lt;/code&gt;默认使用&lt;code&gt;private:&lt;/code&gt;。在继承性上也是这样。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;protect:&lt;/code&gt;允许派生的类访问，其可见性介于两者之间。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;推荐实践
    &lt;div id=&#34;推荐实践&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8e%a8%e8%8d%90%e5%ae%9e%e8%b7%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;不要让成员函数返回引用，否则将会使得成员变量被以外修改。&lt;/li&gt;
&lt;li&gt;不推荐使用成员函数，为了使类的实现更加简洁。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 class=&#34;relative group&#34;&gt;成员初始化列表
    &lt;div id=&#34;成员初始化列表&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%88%90%e5%91%98%e5%88%9d%e5%a7%8b%e5%8c%96%e5%88%97%e8%a1%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;现代 C++ 使用成员初始化列表，而不是直接初始化列表。具体是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;//other...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以前 (C++03) 之前则是用的&lt;code&gt;()&lt;/code&gt;直接初始化。&lt;/p&gt;
&lt;p&gt;成员初始化的顺序和成员初始化列表无关，只跟泪中定义成员变量的顺序有关。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;&lt;code&gt;std::string_view&lt;/code&gt;特殊处理
    &lt;div id=&#34;stdstring_view特殊处理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#stdstring_view%e7%89%b9%e6%ae%8a%e5%a4%84%e7%90%86&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;一个例子：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string_view&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Ball&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_color&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_radius&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Ball&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_color&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;color&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_radius&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;getRadius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Ball&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ball&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Ball(&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ball&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ball&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getRadius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;)&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Ball&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;blue&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;blue&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10.0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;Ball&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;red&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;red&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;12.0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;为什么这里构造函数需要用&lt;code&gt;string_view&lt;/code&gt;作为参数？不能用&lt;code&gt;const string&amp;amp;&lt;/code&gt;来替换？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;string_view&lt;/code&gt;提供了灵活性，如果选择后者，那么如果传入一个 C 语言的字面量字符串的时候，就必须在堆上构建临时的&lt;code&gt;string&lt;/code&gt;对象，而这对性能开销很大；对于前者，永远不会构造临时对象，而是只有一个指针，在真正初始化的时候完成一次复制。(甚至后面还能用移动语义)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为什么&lt;code&gt;getter&lt;/code&gt;不能像上面一样反过来？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因为在类内部的存储对象就是真正的&lt;code&gt;string&lt;/code&gt;，给出它的引用使得外部访问的类型明确，不会造成歧义；同时也提示这个引用的生命周期是明确的————跟成员变量一致。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;构造函数
    &lt;div id=&#34;构造函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;构造函数用于初始化类，在此我们可以手动指定成员变量如何初始化。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;转化构造函数
    &lt;div id=&#34;转化构造函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e8%bd%ac%e5%8c%96%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;转化构造函数其实就是特殊的构造函数，其只拥有一个参数。如果传入一个该参数类型的变量，那么就会自动把这这个变量转化成类。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;默认构造函数
    &lt;div id=&#34;默认构造函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%bb%98%e8%ae%a4%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//可以显式的声明构造函数为默认构造函数，此时 m_a 会被默认初始化为 0。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//用户自己初始化，但是空初始化，此时 m_a 不会被初始化，是垃圾值。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 class=&#34;relative group&#34;&gt;委托构造函数
    &lt;div id=&#34;委托构造函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a7%94%e6%89%98%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;在一个构造函数的&lt;code&gt;:&lt;/code&gt;后面写上参数更多的重载构造函数，可以用另一个构造函数来初始化，但是此构造函数就不能再初始化成员变量。&lt;/p&gt;
&lt;p&gt;尽量不要使用太多的构造函数。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;复制构造函数
    &lt;div id=&#34;复制构造函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a4%8d%e5%88%b6%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;复制构造函数的参数必须是引用，要不然就会发生无限递归的调用复制函数。&lt;/p&gt;
&lt;p&gt;复制构造函数不应用于复制以外的意图，因为编译器可能会发生复制省略 (copy elision)&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;explicit 关键字
    &lt;div id=&#34;explicit-关键字&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#explicit-%e5%85%b3%e9%94%ae%e5%ad%97&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;禁止隐式转换：从单个参数隐式转换成类对象；从列表&lt;code&gt;{xxx,xxx}&lt;/code&gt;转换成类对象。&lt;/p&gt;
&lt;p&gt;在具有单个参数的构造函数前加入，避免编译器执行隐式转换。&lt;/p&gt;
&lt;p&gt;由于 C++ 对于用户定义的转换，只允许转换一次，所以下面的代码会报错：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string_view&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Employee&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Employee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printEmployee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Employee&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// has an Employee parameter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 此时要经历两次转换：C-Style string -&amp;gt; string_view -&amp;gt; class Employee
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;printEmployee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Joe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// compile error
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 修正：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 方法 1:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// using std::literals;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// printEmployee(&amp;#34;Joe&amp;#34;sv);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 方法 2:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// printEmployee(Employee{&amp;#34;Joe&amp;#34;});
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不对复制/移动构造函数使用&lt;code&gt;explicit&lt;/code&gt;，因为他们不执行隐式转换。&lt;/p&gt;
&lt;p&gt;如果转换的时候两者等效且零开销，可以不使用&lt;code&gt;explicit&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;const char*&lt;/code&gt; -&amp;gt; &lt;code&gt;string_view&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt; -&amp;gt; &lt;code&gt;string_view&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 class=&#34;relative group&#34;&gt;constexpr 问题
    &lt;div id=&#34;constexpr-问题&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#constexpr-%e9%97%ae%e9%a2%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;从 C++14 开始，&lt;code&gt;constexpr&lt;/code&gt;修饰函数仅仅是作为编译时求值的提示，如果传入的变量不是一个&lt;code&gt;constexpr&lt;/code&gt;，那么这个函数就具有运行时的上下文，&lt;code&gt;constexpr&lt;/code&gt;修饰就不起作用。&lt;/p&gt;
&lt;p&gt;对于&lt;code&gt;struct&lt;/code&gt;，其作为一个聚合体，默认的构造函数无须加入&lt;code&gt;constexpr&lt;/code&gt;就可以用它初始化一个类对象。但是对于&lt;code&gt;class&lt;/code&gt;，就必须&lt;code&gt;public&lt;/code&gt;，同时手动指定构造函数是&lt;code&gt;constexpr&lt;/code&gt;，比如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;constexpr&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而&lt;code&gt;constexpr&lt;/code&gt;修饰一个类对象的时候，如果涉及到的函数（构造函数、&lt;code&gt;setter&lt;/code&gt;以及使用到的成员函数）都有&lt;code&gt;constexpr&lt;/code&gt;修饰，表示这个类具有编译时的上下文，会让此对象成为一个编译时常量。在编译时如果此对象是用临时对象初始化的，对临时对象是可以修改的，但是一旦这个对象初始化完毕，那么就不再可以修改。&lt;/p&gt;
&lt;p&gt;后续要访问此&lt;code&gt;constexpr&lt;/code&gt;对象，那么所有的函数&lt;code&gt;()&lt;/code&gt;后，都必须有&lt;code&gt;const&lt;/code&gt;，保证不修改此对象。&lt;/p&gt;
&lt;p&gt;参考 (learncpp - 14.17)[https://www.learncpp.com/cpp-tutorial/constexpr-aggregates-and-classes/]&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;this 指针
    &lt;div id=&#34;this-指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#this-%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;指针是一个&lt;code&gt;const&lt;/code&gt;指针（顶层），指向当前操作的类。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;this&lt;/code&gt;指针出现比引用早，不然它多少是个引用。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;成员函数类外定义
    &lt;div id=&#34;成员函数类外定义&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%88%90%e5%91%98%e5%87%bd%e6%95%b0%e7%b1%bb%e5%a4%96%e5%ae%9a%e4%b9%89&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;成员函数可以在类外定义，要加上域访问解析符&lt;code&gt;::&lt;/code&gt;。如果是类的正下方（&lt;code&gt;.h&lt;/code&gt;中），前面加&lt;code&gt;inline&lt;/code&gt;关键字以防止重复包含；如果是对应的 cpp 中，无须加&lt;code&gt;inline&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;默认参数在声明时给出。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;类型模板参数
    &lt;div id=&#34;类型模板参数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b1%bb%e5%9e%8b%e6%a8%a1%e6%9d%bf%e5%8f%82%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;可以在类指定类型模板参数，不过如果成员函数先声明，然后在类外定义，那么需要单独再指定一次模板参数。&lt;/p&gt;
&lt;p&gt;模板类外的成员函数要紧挨着类定义的下面。&lt;/p&gt;
&lt;p&gt;注意：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;所有的模板函数都是默认内联的，所以就算在类外定义，已经隐式&lt;code&gt;inline&lt;/code&gt;了。&lt;/li&gt;
&lt;li&gt;类外定义的函数的类型模板参数必须与类的一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;传入类模板的参数，无须加&lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt;，因为已经在&lt;code&gt;Pair&amp;lt;T&amp;gt;::&lt;/code&gt;作用域中了。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pair&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pair&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// note the parameter has type Pair, not Pair&amp;lt;T&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_first&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pair&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m_first&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_second&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pair&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m_second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;静态成员变量
    &lt;div id=&#34;静态成员变量&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%9d%99%e6%80%81%e6%88%90%e5%91%98%e5%8f%98%e9%87%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;静态成员变量在所有实例化的对象都可用，具有相同的值，在未实例化的时候也可以使用，直接用类名和域访问解析符访问。&lt;/p&gt;
&lt;p&gt;声明的时候，在类内加&lt;code&gt;static&lt;/code&gt;关键字，类外定义不能加关键字。&lt;/p&gt;
&lt;p&gt;位置：直接在类后面/类对应的&lt;code&gt;cpp&lt;/code&gt;，头文件中可以加&lt;code&gt;inline&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;只有静态成员变量可以自动推断，普通的不允许。&lt;/p&gt;
&lt;p&gt;用途：一个根据数量递增的 ID&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;静态成员函数
    &lt;div id=&#34;静态成员函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e9%9d%99%e6%80%81%e6%88%90%e5%91%98%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;静态成员函数用于访问静态全局变量。&lt;/p&gt;
&lt;p&gt;有替代品：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;命名空间：没有访问控制&lt;/li&gt;
&lt;li&gt;静态全局类对象&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class=&#34;relative group&#34;&gt;友元
    &lt;div id=&#34;友元&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8f%8b%e5%85%83&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;在被访问的类中声明，从而使得外部的类/函数能够访问&lt;code&gt;private&lt;/code&gt;和&lt;code&gt;protected&lt;/code&gt;的对象。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;友元函数
    &lt;div id=&#34;友元函数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8f%8b%e5%85%83%e5%87%bd%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;在类中声明，自动成为非成员的函数，类外定义。&lt;/p&gt;
&lt;p&gt;此项特性对于运算符重载非常有用。&lt;/p&gt;

&lt;h4 class=&#34;relative group&#34;&gt;友元类
    &lt;div id=&#34;友元类&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%8f%8b%e5%85%83%e7%b1%bb&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h4&gt;
&lt;p&gt;直接在类内定义。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：引用、右值与函数模板</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-4-reference-rvalue-templates/</link>
      <pubDate>Thu, 25 Sep 2025 16:18:15 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-4-reference-rvalue-templates/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;函数默认参数
    &lt;div id=&#34;函数默认参数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%87%bd%e6%95%b0%e9%bb%98%e8%ae%a4%e5%8f%82%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;声明的时候带默认参数，定义的时候可以不带。但是不能定义的时候有默认参数而声明的时候没有。&lt;/li&gt;
&lt;li&gt;如果用默认参数，那么必须从右到左都有（左边可以没有，不能中断）。&lt;/li&gt;
&lt;li&gt;传入参数的时候，只能从左往右传入，未传入的自动使用默认的参数。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 class=&#34;relative group&#34;&gt;模板
    &lt;div id=&#34;模板&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a8%a1%e6%9d%bf&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;定义：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;typename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;//your function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果还有一个同名的非模板函数：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;调用的时候：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果使用&lt;code&gt;foo()&lt;/code&gt;，那么会直接调用非模板的函数。&lt;/li&gt;
&lt;li&gt;如果用&lt;code&gt;foo&amp;lt;&amp;gt;()&lt;/code&gt;，那么会自动推断，并从模板实例化函数。如果指定类型，则直接从模板按指定的类型实例化函数。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在两个不同的模板参数时，可以定义模板返回用&lt;code&gt;auto&lt;/code&gt;关键字，让编译器自动推导返回类型。这是 C++17 后的 CTAD(class template auto deduction)。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：
CTAD 仅用于推断实参 (argument，调用时)
不能推断形参 (parameter，函数声明)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 C++20 后，函数参数传入&lt;code&gt;auto&lt;/code&gt;会自动变成模板。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;非类型模板：定义&lt;code&gt;constexpr&lt;/code&gt;或者&lt;code&gt;consteval&lt;/code&gt;（C++20）,不写 &lt;code&gt;typename&lt;/code&gt; 。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// print 5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;由于模板展开需要看到定义，所以模板函数应该放在头中。模板不违反单一定义原则。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;左值和右值
    &lt;div id=&#34;左值和右值&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b7%a6%e5%80%bc%e5%92%8c%e5%8f%b3%e5%80%bc&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;左值表达式：在表达式结束之后，还能用标识对象访问的表达式。&lt;/li&gt;
&lt;li&gt;右值表达式：表达式结束之后立即销毁的临时量。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特别：&lt;code&gt;++x&lt;/code&gt;是左值，&lt;code&gt;x++&lt;/code&gt;是右值。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;引用
    &lt;div id=&#34;引用&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%bc%95%e7%94%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;

&lt;h3 class=&#34;relative group&#34;&gt;左值引用
    &lt;div id=&#34;左值引用&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b7%a6%e5%80%bc%e5%bc%95%e7%94%a8&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;左值引用只能绑定到可修改的左值。&lt;/p&gt;
&lt;p&gt;常量左值引用可以绑定到可修改/不可修改的左值，右值。&lt;/p&gt;
&lt;p&gt;一个常量引用可以引用非常量的对应对象，这使得此引用由编译器保证不修改其引用的对象，而且是函数的只读参数的推荐做法。&lt;/p&gt;
&lt;p&gt;如果类型不匹配，引用会尝试将其进行隐式类型转换，得到一个临时对象。需要注意：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;只允许数值提升和非窄化转换。&lt;/li&gt;
&lt;li&gt;此时转化后的临时对象会被引用持有，生命周期与引用本身相同。&lt;/li&gt;
&lt;li&gt;修改原始对象不会对因引用产生的临时对象造成影响。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;小心！引用无法延长函数返回值的声明周期，以下例子为 UB：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getTempVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 class=&#34;relative group&#34;&gt;引用和指针
    &lt;div id=&#34;引用和指针&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%bc%95%e7%94%a8%e5%92%8c%e6%8c%87%e9%92%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;左值引用可以绑定到右值，但是必须是常量的引用才可以。同时，对于右值的常量引用会使得直接绑定的临时对象生命周期被延长。&lt;/p&gt;
&lt;p&gt;而右值引用 (&amp;amp;&amp;amp;) 则是用于移动语义。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;与 auto 相结合
    &lt;div id=&#34;与-auto-相结合&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%8e-auto-%e7%9b%b8%e7%bb%93%e5%90%88&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;顶级&lt;code&gt;const&lt;/code&gt;: 指的是修饰此别名/对象的&lt;code&gt;const&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;低级&lt;code&gt;const&lt;/code&gt;: 指的是被引用绑定/被指针指向的&lt;code&gt;const&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;指针可以同时拥有两种&lt;code&gt;const&lt;/code&gt;，但是引用不行，因为引用不是对象。&lt;/p&gt;
&lt;p&gt;当用&lt;code&gt;auto&lt;/code&gt;关键字以及引用来初始化对象时，遵守：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引用会被删除。&lt;/li&gt;
&lt;li&gt;顶层的常量会被删除。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然可以用&lt;code&gt;auto&amp;amp;&lt;/code&gt;来重新添加引用，不过这样会同时保留顶级的&lt;code&gt;const&lt;/code&gt;。我们一般推荐要手动加上&lt;code&gt;const&lt;/code&gt;，这样会让语义更加清晰。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;constexpr&lt;/code&gt;不是表达式的一部分，所以&lt;code&gt;auto&lt;/code&gt;不会自动推断出它，如果需要则要在 auto 前面手动加上，就像这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;constexpr&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getConstRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;但是推断指针的时候，&lt;code&gt;auto&lt;/code&gt;会完整的保留指针的类型。&lt;/p&gt;
&lt;p&gt;有一点比较特殊，使用&lt;code&gt;const auto&lt;/code&gt;和&lt;code&gt;auto const&lt;/code&gt;是同义的，都会使得新对象成为一个常量的指针。但是如果你想&lt;code&gt;const auto const&lt;/code&gt;，那就会报错。&lt;/p&gt;
&lt;p&gt;如果想要这么做，最好明确一点，就像这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;const auto*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto* const&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;const auto* const&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样就很明显的看出，在*左边的意义是指向常量，在右边的意义是常量的指针，事实上既然都&lt;code&gt;auto&lt;/code&gt;了，也不差这几个关键字吧？我其实比较担心&lt;code&gt;auto&lt;/code&gt;不够智能这个问题。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为什么呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因为指针是一个对象，而引用可以理解成一个别名，所以当我们对引用进行推断的时候，实际上是推断原始的对象究竟是什么类型。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;in/out 参数
    &lt;div id=&#34;inout-参数&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#inout-%e5%8f%82%e6%95%b0&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;为了避免拷贝，可以预先初始化一个对象传入其引用，这样可以避免拷贝，不过使得参数列表很乱。如果可行，还是通过返回值优化或者移动语义。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：类型转换、auto 与标准 I/O</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-3-cast-auto-io/</link>
      <pubDate>Tue, 23 Sep 2025 08:50:10 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-3-cast-auto-io/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;循环，条件与分支
    &lt;div id=&#34;循环条件与分支&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%be%aa%e7%8e%af%e6%9d%a1%e4%bb%b6%e4%b8%8e%e5%88%86%e6%94%af&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;这个东西老生常谈了，我本来没有看的欲望，但是有一道题目很有意思，在此记录：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;从 1 开始，向上计数，将任何只能被 3 整除的数字替换为“fizz”一词，将任何只能被 5 整除的数字替换为“buzz”一词，将任何可被 3 和 5 整除的数字替换为“fizzbuzz”一词，如果还可被 7 整除，那么替换为“fizzbuzzpop”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先，介绍一个名词：分支预测。&lt;/p&gt;
&lt;p&gt;简单来说，现代 CPU 在进行多分支的判断（&lt;code&gt;if-else&lt;/code&gt;）的时候，其实会去猜程序下一步的路径，如果猜对了，那么效率会提升；如果猜错了，那么只能把流水线上面的内容清空，然后重新执行指令。&lt;/p&gt;
&lt;p&gt;所以无论如何，应该尽量避免写&lt;code&gt;if-else&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;题目给出的答案是这么写的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// h/t to reader Waldo for suggesting this quiz
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fizzbuzz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;printed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fizz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;printed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;buzz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;printed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;pop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;printed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// end for loop
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fizzbuzz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;150&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;能运行吗？能，优雅吗？我不太满意。&lt;/p&gt;
&lt;p&gt;所以说，有没有一个办法，不同于这个思路，同时又能更计算机一点？&lt;/p&gt;
&lt;p&gt;评论区的思路：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fizzbuzz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fizz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;buzz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fizzbuzz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;pop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fizzpop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;buzzpop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fizzbuzzpop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;fizzbuzz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个方法非常巧妙，把每一个分支映射到了一个二进制的向量空间上面，这将会极大的提高性能，因为对于 CPU 来说，移位操作是原生的。但是，带来的就是更多相似字符串的重复占用，不知道这是不是良好的实践呢？&lt;/p&gt;
&lt;p&gt;如果还想减少的话，还是用&lt;code&gt;if&lt;/code&gt;来去测试位，不过这样又引入了分支。&lt;/p&gt;
&lt;p&gt;其实这么用的地方还是很多的，POSIX 的权限就是个例子。但是，用的时候就是想不到啊！&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;标准输出，标准错误和标准输入
    &lt;div id=&#34;标准输出标准错误和标准输入&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%a0%87%e5%87%86%e8%be%93%e5%87%ba%e6%a0%87%e5%87%86%e9%94%99%e8%af%af%e5%92%8c%e6%a0%87%e5%87%86%e8%be%93%e5%85%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;这三者是这样的：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;名字&lt;/th&gt;
          &lt;th&gt;文件描述符&lt;/th&gt;
          &lt;th&gt;在 c++ 中的对应&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;标准输入&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;std::cin&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;标准输出&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;std::cout&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;标准错误&lt;/td&gt;
          &lt;td&gt;2&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;std::cerr&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 class=&#34;relative group&#34;&gt;类型转换
    &lt;div id=&#34;类型转换&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%b1%bb%e5%9e%8b%e8%bd%ac%e6%8d%a2&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;

&lt;h3 class=&#34;relative group&#34;&gt;数值提升 (numberic promotion):
    &lt;div id=&#34;数值提升-numberic-promotion&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%95%b0%e5%80%bc%e6%8f%90%e5%8d%87-numberic-promotion&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;同类型，把一个更短的类型转换成一个更长的类型，安全，不会造成精度丢失。&lt;/p&gt;
&lt;p&gt;只有两条路径：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;bool&lt;/code&gt;，有/无负号的短整形，字符型-&amp;gt;&lt;code&gt;int&lt;/code&gt;-&amp;gt;&lt;code&gt;unsigned int&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;float&lt;/code&gt;-&amp;gt;&lt;code&gt;double&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;注意，从&lt;code&gt;int&lt;/code&gt;到&lt;code&gt;long&lt;/code&gt;不是提升，是转换。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;数值转换 (numberic conversion):
    &lt;div id=&#34;数值转换-numberic-conversion&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%95%b0%e5%80%bc%e8%bd%ac%e6%8d%a2-numberic-conversion&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;基本类型的转换，包括：&lt;/p&gt;
&lt;p&gt;窄化 (narrowing conversion)：长的类型转化成一个更短的类型，在{}中不被允许。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但是&lt;code&gt;constexpr&lt;/code&gt;是允许的，因为是编译时求值，所以实际上是截断不是转化。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 class=&#34;relative group&#34;&gt;算术转换 (arithmetic conversion):
    &lt;div id=&#34;算术转换-arithmetic-conversion&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ae%97%e6%9c%af%e8%bd%ac%e6%8d%a2-arithmetic-conversion&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;对基本算术操作符两端的不同类型进行转换，有些规则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;整数转浮点。&lt;/li&gt;
&lt;li&gt;对于无符号/有符号：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;如果没超过有符号上限，那就转换成有符号。&lt;/li&gt;
&lt;li&gt;超过了，那就转换成无符号。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;static_cast&lt;/code&gt;在编译时检查（类型在编译时是确定的），&lt;code&gt;dynamic_cast&lt;/code&gt;在运行时检查。&lt;/p&gt;
&lt;p&gt;不建议使用 C-Style 的转换，因为他可能使用上面中的任意一个以及&lt;code&gt;const_cast&lt;/code&gt;。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;auto
    &lt;div id=&#34;auto&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#auto&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;对于&lt;code&gt;auto&lt;/code&gt;来说，必须要先确定得到的结果是什么，才能做推断，不能对没有初始化值的变量做推断。&lt;/p&gt;
&lt;p&gt;在用&lt;code&gt;std::cin&lt;/code&gt;的时候，给的类型是&lt;code&gt;istream&lt;/code&gt;，所以自动推断会推出这个类型，肯定不是你想要的结果。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;auto&lt;/code&gt;不会保留&lt;code&gt;const&lt;/code&gt;的修饰，所以如果需要保留，用&lt;code&gt;const auto&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;

&lt;h3 class=&#34;relative group&#34;&gt;auto 的尾随返回值
    &lt;div id=&#34;auto-的尾随返回值&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#auto-%e7%9a%84%e5%b0%be%e9%9a%8f%e8%bf%94%e5%9b%9e%e5%80%bc&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;这其实一点都不&lt;code&gt;auto&lt;/code&gt;，只是为了让函数名对齐，然后用&lt;code&gt;-&amp;gt;&lt;/code&gt;给出返回类型罢了。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;divide&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;printSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;generateSubstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：string_view、static 与内部链接</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-2-stringview-static-linkage/</link>
      <pubDate>Fri, 19 Sep 2025 19:13:57 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-2-stringview-static-linkage/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;符号变量
    &lt;div id=&#34;符号变量&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%ac%a6%e5%8f%b7%e5%8f%98%e9%87%8f&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;magic number 这个词，我一直认为是大家约定好了的一组数，但是这里是不同的含义。&lt;/p&gt;
&lt;p&gt;它指的是直接放在函数里面，没有任何交代的数据，使得程序更加难读。&lt;/p&gt;
&lt;p&gt;所以做法一般是推荐用&lt;code&gt;const&lt;/code&gt;修饰，如果标准高的话，&lt;code&gt;constexpr&lt;/code&gt;，请。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;字符串
    &lt;div id=&#34;字符串&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ad%97%e7%ac%a6%e4%b8%b2&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;从 c 开始那么久，都一直没认真了解过字符串，这会终于明白了&lt;code&gt;std::string&lt;/code&gt;的一些基本操作。&lt;/p&gt;
&lt;p&gt;众所周知，字符串里面不可避免包含空白字符，那么办法就是通过&lt;code&gt;std::getline()&lt;/code&gt;，但是如果在&lt;code&gt;std::cin&lt;/code&gt;之后使用，大概率这么传入&lt;code&gt;(std::cin, target)&lt;/code&gt;是无效的，因为&lt;code&gt;cin&lt;/code&gt;在读到空白字符之后会停止，并且把空白字符留在缓冲区，那么下一次读取的时候，直接就把一个&lt;code&gt;\n&lt;/code&gt;传入了，所以你的字符串啥都没有。&lt;/p&gt;
&lt;p&gt;问题解决是通过流操纵符&lt;code&gt;std::ws&lt;/code&gt;（这个需要每次 cin 的时候都提供），控制如果一开始就读取到空白字符，那么就忽略掉这个字符继续读取后面的东西。&lt;/p&gt;
&lt;p&gt;这时就很好的解决了读取到&lt;code&gt;\n&lt;/code&gt;的问题，除非读取到下一个&lt;code&gt;\n&lt;/code&gt;，那么&lt;code&gt;getline&lt;/code&gt;才停止读取，此时字符串也成功存入了这一行。&lt;/p&gt;
&lt;p&gt;怎么说呢，感觉比 c 先进一点点（？&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;string
    &lt;div id=&#34;string&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#string&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;p&gt;因为&lt;code&gt;string&lt;/code&gt;本身就是一个类，其构造函数本身就是重载的，所以无论在初始化的时候传入&lt;code&gt;string&lt;/code&gt;,&lt;code&gt;C-Style string&lt;/code&gt;还是&lt;code&gt;string_view&lt;/code&gt;，都不会发生隐式转换。&lt;/p&gt;
&lt;p&gt;但是如果函数要求的只是一个&lt;code&gt;string&lt;/code&gt;参数，那么把别的类型传入，就会发生编译错误。原因是不允许发生&lt;code&gt;string_view&lt;/code&gt;到&lt;code&gt;string&lt;/code&gt;的窄化转换，性能问题。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;string_view
    &lt;div id=&#34;string_view&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#string_view&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 用 string_view 指向 string 的话，不产生多余的拷贝，只是在初始化的时候拷贝进入 string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;John&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//此处产生拷贝
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name_v&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 不拷贝
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 实际上，是让 string_view 指向一个 c 风格的字符串，这个过程没有拷贝。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;John&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果常量能够在编译时确定，那么就可以应用&lt;code&gt;constexpr&lt;/code&gt;。很显然，前者是不可行的，后者可以。&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ string_view 的行为与普通的引用和指针不一致。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当用&lt;code&gt;string&lt;/code&gt;来初始化&lt;code&gt;string_view&lt;/code&gt;，然后&lt;code&gt;string&lt;/code&gt;被修改之后，&lt;code&gt;string_view&lt;/code&gt;并不会更新&lt;code&gt;string&lt;/code&gt;的新长度。&lt;/p&gt;
&lt;p&gt;如果要避免，得更新视图。（不知道智能指针是否有帮助？）&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;不建议用&lt;code&gt;string_view&lt;/code&gt;来返回，除非它是用 C 式的字符串初始化的。&lt;/p&gt;
&lt;p&gt;对于用&lt;code&gt;string_view&lt;/code&gt;来说，推荐用法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;aaa&amp;#34;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//在堆上分配了 C-Style 字符串，但是用的构造函数不一致，在复制省略中，这是一种过编译的办法。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;实现零成本抽象，原因嘛，以后再补充&amp;hellip;&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;对于流程控制的一些建议
    &lt;div id=&#34;对于流程控制的一些建议&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%af%b9%e4%ba%8e%e6%b5%81%e7%a8%8b%e6%8e%a7%e5%88%b6%e7%9a%84%e4%b8%80%e4%ba%9b%e5%bb%ba%e8%ae%ae&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;对于只有两个分支的&lt;code&gt;if&lt;/code&gt;，可以考虑用三元运算符&lt;code&gt;? :&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果表达式本身只有为&lt;code&gt;0/1&lt;/code&gt;两种可能，那么就无须写&lt;code&gt;==&lt;/code&gt;，直接把表达式扔上去即可。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;static 与内部链接
    &lt;div id=&#34;static-与内部链接&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#static-%e4%b8%8e%e5%86%85%e9%83%a8%e9%93%be%e6%8e%a5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;在变量前加入&lt;code&gt;static&lt;/code&gt;关键字，不仅仅会使变量在整个程序的生命周期有效，还会使得无法被外部文件访问此变量。&lt;/p&gt;
&lt;p&gt;现代 cpp 已经不推荐使用此关键字了。转而替代的是匿名命名空间，后者可以实现里面的变量直接在当前文件访问，其他文件不可访问。&lt;/p&gt;
&lt;p&gt;没加&lt;code&gt;static&lt;/code&gt;的变量默认是全局变量，在别的文件使用&lt;code&gt;extern&lt;/code&gt;引入，&lt;code&gt;const&lt;/code&gt;默认就是内部变量。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;static 的最佳用法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;static&lt;/code&gt;最适合用于函数内的计数场景，比如调用了函数几次，只需在函数内声明一个静态局部变量即可。&lt;/p&gt;
&lt;p&gt;不推荐使用此方法实现相同的输入不同的输出内容，这其实也不符合 fp 的原则。如果必须要这么用，那么最好的办法是将条件一起传入。&lt;a
  href=&#34;https://www.learncpp.com/cpp-tutorial/static-local-variables/&#34;
    target=&#34;_blank&#34;
  &gt;参考&lt;/a&gt;&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;inline 关键字
    &lt;div id=&#34;inline-关键字&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#inline-%e5%85%b3%e9%94%ae%e5%ad%97&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;从 cpp17 开始，完善了&lt;code&gt;inline&lt;/code&gt;，使得&lt;code&gt;constexpr&lt;/code&gt;对于编译时常量跨文件有了最佳解决方案。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;inline&lt;/code&gt;本义其实指的是把函数展开到调用的地方，但是修饰&lt;code&gt;constexpr&lt;/code&gt;时，它被赋予了不同的意义。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;inline&lt;/code&gt;修饰&lt;code&gt;constexpr&lt;/code&gt;特殊，当在多个文件中定义的时候，会告诉链接器从任意一份中取出一份定义，并且在所有文件中共享，同时并不违反 ODR 原则，这使得把&lt;code&gt;inline&lt;/code&gt;放在文件头里面，就可以向引入这个头文件的所有源文件进行分发。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;inline&lt;/code&gt;同时还可以修饰命名空间，修饰非匿名的命名空间可以使得本来需要域解析操作符的使用，直接被透传到全局的命名空间中去。&lt;/p&gt;
&lt;p&gt;下面是一个嵌套的命名空间的例子，使得接口能够安全的对当前文件中的其他函数暴露：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;V1&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// declare a normal namespace named V1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;V1&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;inline&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;V2&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// declare an inline namespace named V2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// unnamed namespace
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// has internal linkage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;V2&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;V1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// calls the V1 version of doSomething()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;V2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// calls the V2 version of doSomething()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// calls the inline version of doSomething() (which is V2)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;inline&lt;/code&gt;作用于&lt;code&gt;V2&lt;/code&gt;命名空间，使得内部内容能够无须域解析操作符，但是匿名命名空间保护性最强，使得内部内容只能有当前文件访问，无法暴露给外部文件。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In modern C++, the term inline has evolved to mean “multiple definitions are allowed”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;总结下，&lt;code&gt;inline&lt;/code&gt;除了内联的意义，其实还有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对于变量：在头文件中定义，使得此头被多次引入的时候只使用共享的一次，避免每次都加载到文件，在头文件被多次引用的时候很有用 (c++17)。同时，如果变量同时被&lt;code&gt;static constexpr&lt;/code&gt;修饰，那么它是隐式&lt;code&gt;inline&lt;/code&gt;的。&lt;/li&gt;
&lt;li&gt;对于函数：在头文件中定义的函数需要加（但是不推荐，等到后面看到类的构造函数再会来补充），声明的函数无须加。&lt;/li&gt;
&lt;li&gt;对于命名空间：把某个命名空间中的内容暴露到全局的命名空间，使得其中内容访问无须加域解析操作符。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 class=&#34;relative group&#34;&gt;using 语句和 using 声明
    &lt;div id=&#34;using-语句和-using-声明&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#using-%e8%af%ad%e5%8f%a5%e5%92%8c-using-%e5%a3%b0%e6%98%8e&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;语句指的是用一个命名空间，这个一般范围过大，不推荐，此处狠狠批评那些教用&lt;code&gt;using namespace std;&lt;/code&gt;的人。&lt;/p&gt;
&lt;p&gt;using 声明是可以接受的，因为它比起别名更加清晰，而不是只让写代码的人看懂。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>现代 C&#43;&#43; 笔记：初始化、字面量与编译期</title>
      <link>https://blog.texsd.eu.org/posts/modern-cpp-1-init-literals-compiletime/</link>
      <pubDate>Thu, 11 Sep 2025 08:10:38 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/modern-cpp-1-init-literals-compiletime/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;前言
    &lt;div id=&#34;前言&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e5%89%8d%e8%a8%80&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;最近找到个个还不错的&lt;a
  href=&#34;https://learncpp.com&#34;
    target=&#34;_blank&#34;
  &gt;网站&lt;/a&gt;，适合我这种大白，遂开始学习，记录一些感受。&lt;/p&gt;
&lt;p&gt;此系列可能没有很好的排版，因为是给自己看的。&lt;/p&gt;
&lt;p&gt;不保证所有的内容一定正确，因为是学习过程中记录的，所以可能还会有完全不正确的理解。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;澄清一个我混淆的概念
    &lt;div id=&#34;澄清一个我混淆的概念&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%be%84%e6%b8%85%e4%b8%80%e4%b8%aa%e6%88%91%e6%b7%b7%e6%b7%86%e7%9a%84%e6%a6%82%e5%bf%b5&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;表达式：求值，调用函数，变量/常量和运算符相结合的东西&lt;/p&gt;
&lt;p&gt;语句：有分号的东西，可以由多个表达式复合而成。&lt;/p&gt;
&lt;p&gt;statement expression（原谅我不会翻译）：只含一个表达式的语句。&lt;/p&gt;
&lt;p&gt;标识符：用户自定义的名称，不以数字开头。&lt;/p&gt;
&lt;p&gt;关键字：系统保留字，用于流程控制。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;cin/cout探秘
    &lt;div id=&#34;cincout探秘&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#cincout%e6%8e%a2%e7%a7%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;我一直好奇，&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;是怎么实现的，还能同时接着，是怎么使用的。&lt;/p&gt;
&lt;p&gt;事实上，这运用的是运算符重载，语义分析会处理左右两边的表达式，然后决定是否重载它。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;是左结合的，所以优先处理左边的部分。&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;一看到左边是一个&lt;code&gt;ostream&lt;/code&gt;类型，右边是一个字符串，自动重载，通过运算返回一个&lt;code&gt;ostream&lt;/code&gt;，接着再处理次级优先的，依次拼接一个完整的字符串流。&lt;/p&gt;
&lt;p&gt;这里提到一个重要概念：副作用。&lt;/p&gt;
&lt;p&gt;正常来说，一个函数应该要返回值。当我们只使用一个&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;的时候，确实只用到了副作用，如果我们连在一起使用的时候，那么返回值就非常重要了。这是不是有点像 fp，给定输入得到输出，接着成为另一个输入？&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;现代的初始化
    &lt;div id=&#34;现代的初始化&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e7%8e%b0%e4%bb%a3%e7%9a%84%e5%88%9d%e5%a7%8b%e5%8c%96&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;现在 c++ 推荐使用列表直接初始化，避免隐式类型转换。&lt;/p&gt;
&lt;p&gt;如：&lt;code&gt;foo{}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;还有别的办法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接初始化：&lt;code&gt;foo(1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;间接列表初始化：&lt;code&gt;foo = {1}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;⚠️不推荐在同一行定义多个变量，因为会在 git 中导致 diff 不清晰。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;literal/variable
    &lt;div id=&#34;literalvariable&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#literalvariable&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;学过微机的人都知道，一个程序加载进内存，会分别放到代码段和数据段，接着获取到一些段（stack，pile）。&lt;/p&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码段是只读的，同时和堆栈段中间还相隔了一些部分，这是避免数据溢出破坏程序的运行。&lt;/li&gt;
&lt;li&gt;对于字面量来说，使用它，就直接到数据段里面取，没有分配给他额外的空间。&lt;/li&gt;
&lt;li&gt;而对于变量来说，使用它，先得从数据段中拷贝一份到栈/堆（假设初始化的话），接着读取这个地址指向的内容，才能进行访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class=&#34;relative group&#34;&gt;compile-time / runtime
    &lt;div id=&#34;compile-time--runtime&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#compile-time--runtime&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;什么是编译时和运行时的概念？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;编译时：编译器在进行语法检查的时候。&lt;/p&gt;
&lt;p&gt;运行时：程序真正运行的时候。&lt;/p&gt;
&lt;p&gt;所以说，我们有下面的内容：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;标识符和编译时相对应，对象和运行时相对应。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;作用域（scope）和编译时对应，生命周期（lifetime）和运行时相对应。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;同时还有一个大杀器：&lt;code&gt;constexpr&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这个关键字的意思，指的是能够在编译时就确定常量（甚至函数），而不是运行时，从而把运行时开销转换成编译时间。&lt;/p&gt;
&lt;p&gt;现在，对于简单的函数，不含&lt;code&gt;new/delete&lt;/code&gt;，&lt;code&gt;cin/cout&lt;/code&gt;，随机数生成的函数，我们都推荐使用&lt;code&gt;constexpr&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;需要注意的是，如果一个常量是在块作用域中，而且初始化用的是常量表达式（&lt;code&gt;{}&lt;/code&gt; &lt;em&gt;零初始化&lt;/em&gt; 是常量表达式），那么它会自动成为常量表达式。&lt;/p&gt;
&lt;p&gt;需要注意的是，在 C++11~20 的不同版本中，支持的类型略有差异，比如后期才支持流程控制的 for/while/if。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;感觉 gemini 这么说不错：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;标识符是编译时的抽象，是对象在代码中的名字和类型。
对象是运行时的实体，是标识符所代表的内存和数据。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 class=&#34;relative group&#34;&gt;cmake 的一些使用方法（对于多文件/引入 libs）
    &lt;div id=&#34;cmake-的一些使用方法对于多文件引入-libs&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#cmake-%e7%9a%84%e4%b8%80%e4%ba%9b%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95%e5%af%b9%e4%ba%8e%e5%a4%9a%e6%96%87%e4%bb%b6%e5%bc%95%e5%85%a5-libs&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;加入这一行把需要的头包含进来，就可以直接在#include 里面写&lt;code&gt;.h&lt;/code&gt;的文件了，无须写相对路径。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cmake&#34; data-lang=&#34;cmake&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;target_include_directories&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;PRIVATE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;CMAKE_CURRENT_SOURCE_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/include/&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 cmake 3.30 之后，引入 Boost 直接用&lt;code&gt;find_package(Boost)&lt;/code&gt;就好。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 class=&#34;relative group&#34;&gt;Best Practise
    &lt;div id=&#34;best-practise&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#best-practise&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;尽量在使用一个变量的正前面初始化。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;尽量不要使用无符号整形，因为其具有的环绕特性会在一些行为（比如与有符号整数比较）上面让人难以调试。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</description>
      
    </item>
    
    <item>
      <title>操作系统笔记：设备与驱动程序</title>
      <link>https://blog.texsd.eu.org/posts/os-1-devices-drivers/io/</link>
      <pubDate>Wed, 02 Jul 2025 11:28:27 +0800</pubDate>
      
      <guid>https://blog.texsd.eu.org/posts/os-1-devices-drivers/io/</guid>
      <description>
&lt;h2 class=&#34;relative group&#34;&gt;插上u盘，是如何工作的？
    &lt;div id=&#34;插上u盘是如何工作的&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8f%92%e4%b8%8au%e7%9b%98%e6%98%af%e5%a6%82%e4%bd%95%e5%b7%a5%e4%bd%9c%e7%9a%84&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;usb控制器检测到电平变化 -&amp;gt; 硬件中断 -&amp;gt; 总线驱动捕获中断 -&amp;gt; sysfs创建设备目录和属性文件 -&amp;gt; 内核通过&lt;code&gt;netlink&lt;/code&gt;发出uevent消息，广播&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;为什么udev的效率高？
    &lt;div id=&#34;为什么udev的效率高&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#%e4%b8%ba%e4%bb%80%e4%b9%88udev%e7%9a%84%e6%95%88%e7%8e%87%e9%ab%98&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;udev被内核发送的uevent唤醒，而不是一直去轮询内核。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;udev是并行工作的。在多个设备插入的时候，为每个事件启动一个处理实例。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;udev使用的Netlink为传递短小的控制信息优化，比其他IPC更加轻量和迅速。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;udev启动的时候会读取所有&lt;code&gt;.rules&lt;/code&gt;文件，并解析成快速查询的内存数据结构。（这个就像mihomo一样，提前把规则处理成一个搜索树，使得匹配效率大幅提高）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 class=&#34;relative group&#34;&gt;I/O设备控制
    &lt;div id=&#34;io设备控制&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#io%e8%ae%be%e5%a4%87%e6%8e%a7%e5%88%b6&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;X86同时支持MMIO/PMIO，ARM只支持MMIO。&lt;/p&gt;
&lt;p&gt;通过一条线，一条指令就可以实现控制。&lt;/p&gt;
&lt;p&gt;控制方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MMIO&lt;/strong&gt;: 把外部控制寄存器映射到内存地址空间。使得一块特定的内存地址不再对应物理RAM。像这块内存地址写入，就是发送到硬件的控制寄存器，而从这里读取，就是获取寄存器当前的状态。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PMIO&lt;/strong&gt;: （微机里面的IN/OUT指令）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;使用内存的地址空间，不会造成存的浪费吗？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;早期的32位系统，你安装了4G内存，会发现只有3.几可用，剩下为硬件保留的内存就是这个原因。一般都是被强制保留给PCIe的MMIO。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;GPIO
    &lt;div id=&#34;gpio&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;
        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#gpio&#34; aria-label=&#34;锚点&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;
    
&lt;/h2&gt;
&lt;p&gt;一个通用的IO，有别于专用IO（USB/HDMI）。可以编程，可以作为输入或者输出。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;输入模式：读取外部世界。通过这个引脚送过来的电平是高或者低来感知外部世界。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输出模式：设置这个引脚为高电平或者低电平，从而控制外部设备。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
      
    </item>
    
  </channel>
</rss>
