<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>类型系统 on Mao's Blog</title><link>https://Mist2233.github.io/tags/%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F/</link><description>Recent content in 类型系统 on Mao's Blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 09 May 2026 20:39:00 +0800</lastBuildDate><atom:link href="https://Mist2233.github.io/tags/%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F/index.xml" rel="self" type="application/rss+xml"/><item><title>4-Designs and Declarations</title><link>https://Mist2233.github.io/posts/4-designsanddeclarations/</link><pubDate>Sat, 09 May 2026 20:39:00 +0800</pubDate><guid>https://Mist2233.github.io/posts/4-designsanddeclarations/</guid><description>&lt;p&gt;本章将介绍设计和声明 C++ 接口的一些原则。&lt;/p&gt;
&lt;h2 id="item18-make-interfaces-easy-to-use-correctly-and-hard-to-use-incorrectly"&gt;Item18: Make interfaces easy to use correctly and hard to use incorrectly&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;核心思想&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;好的接口应该&lt;strong&gt;引导正确使用，阻止错误使用&lt;/strong&gt;。如果用户用错了，编译器应该报错，而不是运行时才发现 bug。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以，我们在设计接口的时候，最好多问自己一个问题：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;如果别人用我的接口，最可能的几种用错方式是什么？我能不能在编译期就拦住，从而让用户正确地使用接口？&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;具体来说，主要有下面四个点需要检查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;参数顺序容易搞混吗？ -&amp;gt; 用类型区分&lt;/li&gt;
&lt;li&gt;参数有合法范围吗？ -&amp;gt; 用 &lt;code&gt;enum&lt;/code&gt; 或者 &lt;code&gt;enum class&lt;/code&gt; 限定范围&lt;/li&gt;
&lt;li&gt;行为和内置类型一致吗？ -&amp;gt; 该 &lt;code&gt;const&lt;/code&gt; 就 &lt;code&gt;const&lt;/code&gt;，该重载运算符就重载&lt;/li&gt;
&lt;li&gt;涉及资源管理吗？ -&amp;gt; 返回智能指针，不要返回裸指针&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="参数顺序容易搞混吗"&gt;参数顺序容易搞混吗？&lt;/h3&gt;
&lt;p&gt;比如说，我有一个 &lt;code&gt;Date&lt;/code&gt; 类，它的构造函数需要三个参数：month-day-year。如果我全都定义成 &lt;code&gt;int&lt;/code&gt; 类型，那么在传错顺序时很难检查出来。&lt;/p&gt;
&lt;p&gt;所以，我可以自定义新的三个类：&lt;code&gt;Month&lt;/code&gt;、&lt;code&gt;Day&lt;/code&gt; 和 &lt;code&gt;Year&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 危险：三个 int，顺序很容易传反
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 改进：用类型区分
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Month&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;explicit&lt;/span&gt; &lt;span class="nf"&gt;Month&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Day&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;explicit&lt;/span&gt; &lt;span class="nf"&gt;Day&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;explicit&lt;/span&gt; &lt;span class="nf"&gt;Year&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Month&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Day&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Year&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样，就可以轻松区分下面三种情况，用户很难传错参数：&lt;/p&gt;</description></item><item><title>SFINAE原则</title><link>https://Mist2233.github.io/posts/sfinae%E5%8E%9F%E5%88%99/</link><pubDate>Tue, 02 Dec 2025 09:12:51 +0800</pubDate><guid>https://Mist2233.github.io/posts/sfinae%E5%8E%9F%E5%88%99/</guid><description>&lt;h2 id="sfinae-substitution-failure-is-not-an-error"&gt;SFINAE (Substitution Failure Is Not An Error)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 我们之前聊过模板。在 C++ 模板编程中，有一个非常著名的缩写词叫 &lt;strong&gt;SFINAE&lt;/strong&gt; (读作 &amp;ldquo;sfi-nay&amp;rdquo;)。&lt;/p&gt;
&lt;p&gt;请问，你知道 SFINAE 代表什么意思吗？或者你能简单描述一下，当编译器在实例化模板时，如果遇到了一个&lt;strong&gt;无效的类型替换&lt;/strong&gt;，它会怎么做？是直接报错停止编译，还是会尝试别的方案？&lt;/p&gt;
&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不好意思，我第一次听说“模板元编程”这个概念，也是第一次听说 SFINAE 这个名词，请你直接解释吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;没关系！这正是我们今天学习的意义所在。模板元编程是 C++ 的深水区，SFINAE 是进入这个世界的敲门砖。&lt;/p&gt;
&lt;p&gt;我们把这个复杂的概念拆解成最简单的逻辑。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="什么是-sfinae"&gt;什么是 SFINAE？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;SFINAE&lt;/strong&gt; 代表 &lt;strong&gt;&amp;ldquo;Substitution Failure Is Not An Error&amp;rdquo;&lt;/strong&gt;。
中文直译：&lt;strong&gt;“替换失败不是错误”&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这听起来像是一句哲学名言，但在 C++ 编译器眼中，它是一条非常具体的&lt;strong&gt;生存法则&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="场景重现编译器的选秀大会"&gt;场景重现：编译器的选秀大会&lt;/h3&gt;
&lt;p&gt;假设你写了两个同名的函数模板 &lt;code&gt;foo&lt;/code&gt;（这叫重载）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 选手 A：这个模板要求 T 必须有一个叫 inner_type 的内部类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;inner_type&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Selected A&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 选手 B：这个模板对 T 没有任何要求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Selected B&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;现在，你在 &lt;code&gt;main&lt;/code&gt; 函数里调用了 &lt;code&gt;foo(10)&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>命名空间</title><link>https://Mist2233.github.io/posts/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4/</link><pubDate>Wed, 26 Nov 2025 08:38:45 +0800</pubDate><guid>https://Mist2233.github.io/posts/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4/</guid><description>&lt;h2 id="命名空间-namespace"&gt;命名空间 namespace&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++ 中，我们经常看到 &lt;code&gt;std::cout&lt;/code&gt;、&lt;code&gt;std::vector&lt;/code&gt; 这样的写法，这里的 &lt;code&gt;std&lt;/code&gt; 就是一个&lt;strong&gt;命名空间&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;请问，&lt;strong&gt;命名空间 (namespace)&lt;/strong&gt; 的主要作用是什么？它解决了 C++（以及很多其他编程语言）中一个什么样的痛点？&lt;/p&gt;
&lt;p&gt;此外，我们在 &lt;code&gt;.cpp&lt;/code&gt; 文件中经常会看到 &lt;code&gt;using namespace std;&lt;/code&gt; 这样的写法。请问，在&lt;strong&gt;头文件 (&lt;code&gt;.h&lt;/code&gt;)&lt;/strong&gt; 中使用 &lt;code&gt;using namespace std;&lt;/code&gt; 是一个好的习惯吗？为什么？&lt;/p&gt;
&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我认为，命名空间类似一个集合，里面包含着特定的“工具”，也就是函数。我们把一些常用的、标准的工具打包起来，就变成了一个命名空间。&lt;/li&gt;
&lt;li&gt;同时，命名空间也是一个前缀。它解决的痛点是：如何区分不同位置的同名函数？通过命名空间就可以。比如说，&lt;code&gt;A&lt;/code&gt; 和 &lt;code&gt;B&lt;/code&gt; 两个命名空间都有一个函数叫做 &lt;code&gt;test&lt;/code&gt;，那么我们可以通过 &lt;code&gt;A::test&lt;/code&gt; 和 &lt;code&gt;B::test&lt;/code&gt; 来分别调用这两个不同的函数，而不会导致混淆。&lt;/li&gt;
&lt;li&gt;你提到的最后一点：在头文件中使用 &lt;code&gt;using namespace std;&lt;/code&gt;。这绝对不是一个好习惯！简单来说，它会导致命名空间污染的问题。即：我在头文件里使用 &lt;code&gt;using namespace std;&lt;/code&gt;，在所有导入该头文件的文件中，命名空间都会被默认设置为 &lt;code&gt;std&lt;/code&gt;。一旦我们自己定义的函数和 &lt;code&gt;std&lt;/code&gt; 中的某个函数重名，在调用时会导致混乱，通常会调用 &lt;code&gt;std&lt;/code&gt; 中的那个函数。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我只是凭自己理解作答，如果不正确，请你指出。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;你的回答&lt;strong&gt;极其出色&lt;/strong&gt;！虽然你说是一个月没学，但你的 C++ 感觉依然非常敏锐。&lt;/p&gt;
&lt;p&gt;我们来逐点分析你的回答：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;命名空间的定义&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“命名空间类似一个集合&amp;hellip; 也是一个前缀。”&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;这个比喻非常形象！命名空间本质上就是一个&lt;strong&gt;逻辑上的作用域&lt;/strong&gt;。它把一组相关的标识符（函数、类、变量等）包裹起来，像是一个&lt;strong&gt;虚拟的文件夹&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解决的痛点&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“解决的痛点是：如何区分不同位置的同名函数？”&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;完全正确！这就是&lt;strong&gt;命名冲突 (Name Collision)&lt;/strong&gt; 问题。在大型项目中，成千上万的代码、引入几十个第三方库，如果没有命名空间，大家为了给函数起个不重名的名字（比如 &lt;code&gt;LibA_test&lt;/code&gt;, &lt;code&gt;MyProj_test&lt;/code&gt;），头都要炸了。命名空间优雅地解决了这个问题。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;头文件中的 &lt;code&gt;using namespace std;&lt;/code&gt;&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>C++类型转换符</title><link>https://Mist2233.github.io/posts/c++%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E7%AC%A6/</link><pubDate>Tue, 21 Oct 2025 08:28:49 +0800</pubDate><guid>https://Mist2233.github.io/posts/c++%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E7%AC%A6/</guid><description>&lt;p&gt;&lt;strong&gt;我们开始今天的 C++ 八股环节！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;今天，我们来聊一个在面试中经常被用来考察你对 C++ 基础和面向对象理解的话题：&lt;strong&gt;&lt;code&gt;static_cast&lt;/code&gt;, &lt;code&gt;dynamic_cast&lt;/code&gt;, &lt;code&gt;const_cast&lt;/code&gt;, &lt;code&gt;reinterpret_cast&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这四个是 C++ 的标准类型转换操作符。相比于 C 风格的强制转换（如 &lt;code&gt;(int)x&lt;/code&gt;），它们更安全、意图也更明确。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="static_cast-转换符"&gt;&lt;code&gt;static_cast&lt;/code&gt; 转换符&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;模拟面试开始&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++ 中，我们有四种“具名”的类型转换符，统称为 &lt;code&gt;static_cast&lt;/code&gt; 系列。我们先来聊聊最常用的一个：&lt;strong&gt;&lt;code&gt;static_cast&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;请问，&lt;code&gt;static_cast&lt;/code&gt; 主要用于什么样的转换场景？它和 C 风格的强制转换 &lt;code&gt;(new_type)expression&lt;/code&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;static_cast&lt;/code&gt; 是 C++ 中最基础和最简单的类型转换，主要有以下的应用场景：
&lt;ul&gt;
&lt;li&gt;相关类型之间的转换，如数值类型之间、枚举类型和整数之间、&lt;code&gt;void*&lt;/code&gt; 类型和其他指针类型之间。&lt;/li&gt;
&lt;li&gt;有继承关系的类指针/引用转换（不涉及多态的情况）。这里，将派生类指针或引用，转为基类的指针或引用（也就是上行转换）是安全的；反之，将基类的指针或者引用，转为派生类的指针或者引用（也就是下行转换）是不安全的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;和 &lt;code&gt;(new_type)expression&lt;/code&gt; 相比，&lt;code&gt;static_cast&lt;/code&gt; 的转换意图更明确（从命名就可以看出），以及转换过程更安全（会检查变量类型之间是否可以安全转换）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;面试官 (总结与补充):&lt;/strong&gt; 你说的完全正确。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;static_cast&lt;/code&gt; 是 C++ 中最基础、最常用的“良性”转换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主要应用场景：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;相关类型之间的转换&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数值类型转换&lt;/strong&gt;：在各种数值类型之间进行转换，比如 &lt;code&gt;int&lt;/code&gt; -&amp;gt; &lt;code&gt;double&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt; -&amp;gt; &lt;code&gt;int&lt;/code&gt;。
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// i = 3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;枚举与整数转换&lt;/strong&gt;：在枚举类型和整数类型之间进行转换。
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;RED&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;em&gt;void&lt;/em&gt; 指针转换&lt;/em&gt;*：将 &lt;code&gt;void*&lt;/code&gt; 指针转换为具体的类型指针。
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;有继承关系的类指针/引用转换 (不涉及多态)&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>Const关键字</title><link>https://Mist2233.github.io/posts/const%E5%85%B3%E9%94%AE%E5%AD%97/</link><pubDate>Thu, 09 Oct 2025 13:09:59 +0800</pubDate><guid>https://Mist2233.github.io/posts/const%E5%85%B3%E9%94%AE%E5%AD%97/</guid><description>&lt;h2 id="const-修饰变量"&gt;&lt;code&gt;const&lt;/code&gt; 修饰变量&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 看到你的简历上写着熟悉 C++，那我们来聊聊 &lt;code&gt;const&lt;/code&gt; 关键字吧。它在 C++ 中有很多用途。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我的第一个问题是：&lt;/strong&gt; 当 &lt;code&gt;const&lt;/code&gt; 用于修饰一个&lt;strong&gt;变量&lt;/strong&gt;时，它意味着什么？它和 C 语言中的 &lt;code&gt;#define&lt;/code&gt; 宏定义常量相比，有什么主要的优势？&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 方式一
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;MAX_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 方式二
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define MAX_SIZE 100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;const&lt;/code&gt; 关键字修饰变量，表示这个变量是一个常量，不能被修改。&lt;/li&gt;
&lt;li&gt;和 &lt;code&gt;#define&lt;/code&gt; 宏定义常量相比，&lt;code&gt;const&lt;/code&gt; 变量更加有下面的优势：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类型检查&lt;/strong&gt;：&lt;code&gt;const&lt;/code&gt; 是有类型的变量，编译器会进行类型检查，而 &lt;code&gt;#define&lt;/code&gt; 是纯文本变量，没有类型概念，容易引发隐性错误——编译通过但运行出错。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作用域控制&lt;/strong&gt;：&lt;code&gt;const&lt;/code&gt; 类型的变量可以定义在局部作用域中，而 &lt;code&gt;#define&lt;/code&gt; 是全局替换，容易产生命名冲突&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调试支持&lt;/strong&gt;：&lt;code&gt;const&lt;/code&gt; 变量可以在调试器中查看它的值和地址，而 &lt;code&gt;#define&lt;/code&gt; 变量在预处理阶段就被替换到，调试器无法识别。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;取地址操作&lt;/strong&gt;：&lt;code&gt;const&lt;/code&gt; 变量可以取地址，而 &lt;code&gt;#define&lt;/code&gt; 是文本替换，没有地址的概念。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨文件访问&lt;/strong&gt;：&lt;code&gt;const&lt;/code&gt; 变量可以通过 &lt;code&gt;extern&lt;/code&gt; 声明在多个文件中共享，而 &lt;code&gt;#define&lt;/code&gt; 无法跨文件共享，只能重新定义。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;当然，&lt;code&gt;const&lt;/code&gt; 最主要的优势还是&lt;strong&gt;类型检查&lt;/strong&gt;和&lt;strong&gt;作用域控制&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="const-与指针结合"&gt;&lt;code&gt;const&lt;/code&gt; 与指针结合&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官 (继续提问):&lt;/strong&gt; 好的，你对 &lt;code&gt;const&lt;/code&gt; 修饰普通变量的理解非常透彻。我们来看它和&lt;strong&gt;指针&lt;/strong&gt;的结合。&lt;/p&gt;
&lt;p&gt;请你解释一下，下面这三种声明中，&lt;code&gt;p&lt;/code&gt; 的类型有什么不同？分别都约束了什么东西不能被修改？&lt;/p&gt;</description></item><item><title>模板：template和typename</title><link>https://Mist2233.github.io/posts/%E6%A8%A1%E6%9D%BFtemplate%E5%92%8Ctypename/</link><pubDate>Mon, 29 Sep 2025 09:33:17 +0800</pubDate><guid>https://Mist2233.github.io/posts/%E6%A8%A1%E6%9D%BFtemplate%E5%92%8Ctypename/</guid><description>&lt;h2 id="模板的作用与分类"&gt;模板的作用与分类&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++ 中，&lt;strong&gt;模板 (template)&lt;/strong&gt; 是实现泛型编程的核心机制。&lt;/p&gt;
&lt;p&gt;你能用自己的话，简单解释一下什么是模板吗？它主要解决了什么问题？C++ 中主要有哪几种类型的模板？&lt;/p&gt;
&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模板是 Cpp 的一种机制，它允许我们编写&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;li&gt;C++中主要的模板，我认为有
&lt;ul&gt;
&lt;li&gt;函数模板：处理任意类型参数的模板&lt;/li&gt;
&lt;li&gt;类模板：处理任意类型成员的模板。&lt;/li&gt;
&lt;li&gt;模板特化：某一个具体类型需要特殊实现，提供一个特化类型的模板。&lt;/li&gt;
&lt;li&gt;模板偏特化：允许对模板参数的一部分特化，不过较为复杂，使用较少。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="模板实例化-template-instantiation"&gt;模板实例化 Template Instantiation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官 (追问):&lt;/strong&gt; 好的，你提到了函数模板和类模板。我们知道，模板本身并不是可以直接执行的代码，它更像是一个“蓝图”。&lt;/p&gt;
&lt;p&gt;请问，从“模板蓝图”到“可执行代码”这个过程，是在什么时候发生的？这个过程通常被称为什么？&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 发生了什么？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.71&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 这里又发生了什么？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从“模板蓝图”到“可执行代码”这个过程，是在调用函数时，编译器识别到参数的具体类型时发生的。&lt;/li&gt;
&lt;li&gt;在上面的例子中，第一个 &lt;code&gt;add&lt;/code&gt; 函数识别到输入的参数为 &lt;code&gt;int&lt;/code&gt; 类型，因此执行 &lt;code&gt;int&lt;/code&gt; 类型的加法；而第二个 &lt;code&gt;add&lt;/code&gt; 函数识别到输入的参数为 &lt;code&gt;double&lt;/code&gt; 类型，因此执行 &lt;code&gt;double&lt;/code&gt; 类型的加法。&lt;/li&gt;
&lt;li&gt;这个过程被称为&lt;strong&gt;模板实例化&lt;/strong&gt;。
&lt;ul&gt;
&lt;li&gt;在上面的例子中，模板实例化由编译器自动完成，而不是程序员手动指定，这样的实例化过程被称为隐式实例化 (Implicit Instantiation)。&lt;/li&gt;
&lt;li&gt;而程序员手动指定类型并提前生成代码的实例化，被称为显式实例化 (Explicit Instantiation)。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是一个基于 &lt;code&gt;add&lt;/code&gt; 函数的显式实例化的例子：&lt;/p&gt;</description></item><item><title>using关键字</title><link>https://Mist2233.github.io/posts/using%E5%85%B3%E9%94%AE%E5%AD%97/</link><pubDate>Wed, 24 Sep 2025 09:26:08 +0800</pubDate><guid>https://Mist2233.github.io/posts/using%E5%85%B3%E9%94%AE%E5%AD%97/</guid><description>&lt;h2 id="using-声明和-using-指令"&gt;&lt;code&gt;using&lt;/code&gt; 声明和 &lt;code&gt;using&lt;/code&gt; 指令&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++ 中，&lt;code&gt;using&lt;/code&gt; 关键字有多种用途。我们先来聊聊它最常见的两种用法：&lt;strong&gt;&lt;code&gt;using&lt;/code&gt; 声明 (using-declaration)&lt;/strong&gt; 和 &lt;strong&gt;&lt;code&gt;using&lt;/code&gt; 指令 (using-directive)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;请问，下面这两行代码，它们分别属于哪一种？它们在作用和影响范围上，有什么本质的区别？&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 场景一
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 这是什么？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 场景二
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 这又是什么？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;World&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;using std::cout&lt;/code&gt; 属于 &lt;code&gt;using&lt;/code&gt; 声明，它只引入命名空间中的单个成员，作用在当前作用域中，适合局部使用。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;using namespace std&lt;/code&gt; 属于 &lt;code&gt;using&lt;/code&gt; 指令，它负责引入整个命名空间，作用在全局，但容易导致二义性问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;面试官 (总结与肯定):&lt;/strong&gt; 你说的完全正确。&lt;/p&gt;</description></item><item><title>inline内联函数</title><link>https://Mist2233.github.io/posts/inline%E5%86%85%E8%81%94%E5%87%BD%E6%95%B0/</link><pubDate>Mon, 22 Sep 2025 08:39:31 +0800</pubDate><guid>https://Mist2233.github.io/posts/inline%E5%86%85%E8%81%94%E5%87%BD%E6%95%B0/</guid><description>&lt;h2 id="inline-的好处与坏处"&gt;&lt;code&gt;inline&lt;/code&gt; 的好处与坏处&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++ 中，我们可以在函数声明或定义前，加上 &lt;code&gt;inline&lt;/code&gt; 关键字。&lt;/p&gt;
&lt;p&gt;请问，&lt;code&gt;inline&lt;/code&gt; 关键字是用来做什么的？它是在向编译器&lt;strong&gt;建议&lt;/strong&gt;什么？使用内联函数，主要可能带来什么&lt;strong&gt;好处&lt;/strong&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;inline&lt;/code&gt; 关键字用于声明内联函数，它在向编译器建议：“这个函数代码很短，请你将它的代码直接嵌入我们调用它的地方，而不用进行调用跳转。”&lt;/li&gt;
&lt;li&gt;当然，这只是一个建议，编译器有最终的决定权。如果编译器觉得这个函数过于复杂，那么它会忽略 &lt;code&gt;inline&lt;/code&gt; 的建议，仍然执行调用跳转。&lt;/li&gt;
&lt;li&gt;好处：
&lt;ul&gt;
&lt;li&gt;使用内联函数，尤其是对短小且频繁调用的函数，可以省去函数调用的开销，执行效率更高。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;坏处：
&lt;ul&gt;
&lt;li&gt;编译更加复杂，导致编译时间增加。&lt;/li&gt;
&lt;li&gt;由于每次都要复制一份函数体代码到调用处，因此代码膨胀，且指令数量增加，指令缓存效率受影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&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;ul&gt;
&lt;li&gt;&lt;strong&gt;参数压栈&lt;/strong&gt;：将函数参数按照调用约定压入栈中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回地址压栈&lt;/strong&gt;：将调用点下一条指令的地址压入栈中，以便函数返回时能继续执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跳转&lt;/strong&gt;：CPU 执行 &lt;code&gt;call&lt;/code&gt; 指令，跳转到函数体的入口地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;栈帧建立&lt;/strong&gt;：为函数的局部变量分配栈空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;函数返回&lt;/strong&gt;：执行 &lt;code&gt;ret&lt;/code&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;inline&lt;/code&gt; 的目的就是消除这些“行政”开销。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你提到的坏处——代码膨胀 (Code Bloat)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这是一个非常重要的权衡。如果一个函数体本身很大，内联它会导致可执行文件的体积急剧增大。&lt;/li&gt;
&lt;li&gt;这不仅占用更多磁盘空间，更重要的是，它会破坏&lt;strong&gt;指令缓存 (Instruction Cache, i-cache) 的局部性&lt;/strong&gt;。CPU 访问内存的速度远慢于执行指令的速度，所以它会把最近用到的指令缓存起来。如果代码体积太大，缓存装不下，就会导致频繁的“缓存未命中 (cache miss)”，CPU 需要去慢速的主存中读取指令，反而降低了程序的整体性能。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;编译器的决定权&lt;/strong&gt;
现代编译器非常智能，它在决定是否内联时，通常会自己做判断，即使你没有加 &lt;code&gt;inline&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它会&lt;strong&gt;自动内联&lt;/strong&gt;它认为合适的、足够简单的函数（比如定义在类头文件中的成员函数，默认就是 &lt;code&gt;inline&lt;/code&gt; 的）。&lt;/li&gt;
&lt;li&gt;它会&lt;strong&gt;拒绝内联&lt;/strong&gt;过于复杂的函数，即使你加了 &lt;code&gt;inline&lt;/code&gt; 关键字。比如，包含循环、递归、大量 &lt;code&gt;switch&lt;/code&gt; 的函数通常不会被内联。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="inline-的语法作用解决-odr-违例问题"&gt;&lt;code&gt;inline&lt;/code&gt; 的语法作用——解决 ODR 违例问题&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官 (深入提问):&lt;/strong&gt; 好的，你对 &lt;code&gt;inline&lt;/code&gt; 的性能考量已经很清楚了。&lt;/p&gt;</description></item><item><title>NULL和nullptr</title><link>https://Mist2233.github.io/posts/null%E5%92%8Cnullptr/</link><pubDate>Thu, 18 Sep 2025 08:33:33 +0800</pubDate><guid>https://Mist2233.github.io/posts/null%E5%92%8Cnullptr/</guid><description>&lt;h2 id="nullptr-解决函数重载的二义性"&gt;&lt;code&gt;nullptr&lt;/code&gt; 解决函数重载的二义性&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++11 之前，我们通常使用一个宏 &lt;code&gt;NULL&lt;/code&gt; 来表示空指针。而在 C++11 中，引入了一个新的关键字 &lt;code&gt;nullptr&lt;/code&gt; 来专门表示空指针。&lt;/p&gt;
&lt;p&gt;请问，我们为什么需要 &lt;code&gt;nullptr&lt;/code&gt;？或者说，使用宏 &lt;code&gt;NULL&lt;/code&gt; 在某些情况下，会带来什么样的问题或歧义，是 &lt;code&gt;nullptr&lt;/code&gt; 能够解决的？&lt;/p&gt;
&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NULL&lt;/code&gt; 是一个宏，它除了表示空指针之外，更常用的含义是表示 &lt;code&gt;0&lt;/code&gt;，一个整数。&lt;/li&gt;
&lt;li&gt;由于 &lt;code&gt;NULL&lt;/code&gt; 既能表示空指针，又能表示 &lt;code&gt;0&lt;/code&gt;，因此它会引发歧义。&lt;/li&gt;
&lt;li&gt;比如，某个函数重载了两个版本，一个的参数类型是 &lt;code&gt;int&lt;/code&gt;，而另一个参数类型是 &lt;code&gt;char*&lt;/code&gt;。当输入 &lt;code&gt;NULL&lt;/code&gt; 时，通常会调用参数为 &lt;code&gt;int&lt;/code&gt; 的那个版本。&lt;/li&gt;
&lt;li&gt;而使用 &lt;code&gt;nullptr&lt;/code&gt; 则规避了这一风险。&lt;code&gt;nullptr&lt;/code&gt; 是一个真正的空指针常量，它是一个特殊的类型 &lt;code&gt;std::nullptr_t&lt;/code&gt;，可以隐式地转换为任何的指针类型，而不会和 &lt;code&gt;int&lt;/code&gt; 类型混淆。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;面试官 (总结与肯定):&lt;/strong&gt; 你说的完全正确。我们来把这个过程再详细地梳理一遍。&lt;code&gt;nullptr&lt;/code&gt; 诞生的&lt;strong&gt;核心原因&lt;/strong&gt;是&lt;strong&gt;解决函数重载时的二义性&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;NULL&lt;/code&gt; 的“前世今生”&lt;/strong&gt;
&lt;code&gt;NULL&lt;/code&gt; 是一个定义在 &lt;code&gt;&amp;lt;cstddef&amp;gt;&lt;/code&gt; 等头文件中的&lt;strong&gt;预处理宏&lt;/strong&gt;。它的具体定义取决于编译器，但通常是下面两种之一：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define NULL 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 或者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define NULL 0L
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 或者在 C++ 编译器中，有时甚至是
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define NULL nullptr &lt;/span&gt;&lt;span class="c1"&gt;// 这是现代编译器的“向后兼容”行为
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 C++98/03 的时代，你可以认为 &lt;code&gt;NULL&lt;/code&gt; 就是一个值为 &lt;code&gt;0&lt;/code&gt; 的&lt;strong&gt;整型常量&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>Cpp的三种类型推导关键字</title><link>https://Mist2233.github.io/posts/cpp%E7%9A%84%E4%B8%89%E7%A7%8D%E7%B1%BB%E5%9E%8B%E6%8E%A8%E5%AF%BC%E5%85%B3%E9%94%AE%E5%AD%97/</link><pubDate>Sun, 14 Sep 2025 09:33:26 +0800</pubDate><guid>https://Mist2233.github.io/posts/cpp%E7%9A%84%E4%B8%89%E7%A7%8D%E7%B1%BB%E5%9E%8B%E6%8E%A8%E5%AF%BC%E5%85%B3%E9%94%AE%E5%AD%97/</guid><description>&lt;h2 id="auto-关键字"&gt;&lt;code&gt;auto&lt;/code&gt; 关键字&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; C++11 引入了 &lt;code&gt;auto&lt;/code&gt; 关键字，它极大地改变了我们编写 C++ 代码的方式。&lt;/p&gt;
&lt;p&gt;你能简单解释一下，&lt;code&gt;auto&lt;/code&gt; 关键字的作用是什么吗？使用它有什么好处？&lt;/p&gt;
&lt;p&gt;回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;auto&lt;/code&gt; 关键字的作用是，省略具体的变量类型，而是根据实际变量的类型推导出其类型。&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;auto&lt;/code&gt; 关键字，就不必写复杂的类型名（比如常用的 STL 迭代器），让代码看上去更简洁。&lt;/li&gt;
&lt;li&gt;同时，&lt;code&gt;auto&lt;/code&gt; 关键字还能实现类似“多态”的效果（这里说“多态”不太准确，应该说，是泛型编程），使得同一份代码可以被许多不同的类型复用。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;面试官 (补充与澄清):&lt;/strong&gt; 你说的很对。我们来把你的回答再精确化和补充一下。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;auto&lt;/code&gt; 的作用：&lt;/strong&gt;
它是一个&lt;strong&gt;类型占位符&lt;/strong&gt;。编译器会在&lt;strong&gt;编译时&lt;/strong&gt;，根据变量的&lt;strong&gt;初始化表达式&lt;/strong&gt;，自动推导出变量应该具有的正确类型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;auto&lt;/code&gt; 的好处：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;简洁性 (Brevity)&lt;/strong&gt;：正如你所说，它可以避免写冗长、复杂的类型名。这一点在处理 STL 的&lt;strong&gt;迭代器&lt;/strong&gt;和&lt;strong&gt;模板&lt;/strong&gt;时尤其明显。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// C++03
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_vec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// C++11 with auto
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_vec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 简洁、易读、不易出错
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;正确性 (Correctness)&lt;/strong&gt;：&lt;code&gt;auto&lt;/code&gt; 保证了变量的类型与初始化表达式的类型&lt;strong&gt;完全匹配&lt;/strong&gt;，避免了因手写类型错误或发生意外的类型转换而导致的 bug。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;可维护性 (Maintainability)&lt;/strong&gt;：如果初始化表达式的类型未来发生了变化（比如一个函数的返回值从 &lt;code&gt;int&lt;/code&gt; 变成了 &lt;code&gt;long long&lt;/code&gt;），使用了 &lt;code&gt;auto&lt;/code&gt; 的代码&lt;strong&gt;不需要任何修改&lt;/strong&gt;，会自动适应新的类型。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;关于你提到的“多态效果”：&lt;/strong&gt;
这个描述非常有趣！&lt;code&gt;auto&lt;/code&gt; 本身是在编译期进行类型推导，不直接产生运行时的多态（那需要虚函数）。但你说的“使得同一份代码可以被许多不同的类型复用”，这个思想非常接近&lt;strong&gt;泛型编程 (Generic Programming)&lt;/strong&gt;。
&lt;code&gt;auto&lt;/code&gt; 在 C++14 的&lt;strong&gt;泛型 Lambda&lt;/strong&gt; 中 &lt;code&gt;[](auto x){ ... }&lt;/code&gt; 和 C++20 的&lt;strong&gt;函数参数&lt;/strong&gt;中 &lt;code&gt;void func(auto param)&lt;/code&gt;，确实扮演了类似模板参数的角色，让一段代码能适用于多种类型。你的直觉是非常准的。&lt;/p&gt;</description></item><item><title>左值与右值</title><link>https://Mist2233.github.io/posts/%E5%B7%A6%E5%80%BC%E4%B8%8E%E5%8F%B3%E5%80%BC/</link><pubDate>Tue, 09 Sep 2025 10:09:30 +0800</pubDate><guid>https://Mist2233.github.io/posts/%E5%B7%A6%E5%80%BC%E4%B8%8E%E5%8F%B3%E5%80%BC/</guid><description>&lt;h2 id="什么是左值什么是右值如何区分它们"&gt;什么是左值？什么是右值？如何区分它们？&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官：&lt;/strong&gt; 在 C++ 中，我们经常听到“左值”和“右值”这两个术语。你能用自己的话，简单地解释一下，什么是左值，什么是右值吗？最简单的区分它们的方法是什么？&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;p&gt;&lt;strong&gt;面试官 (补充与深化):&lt;/strong&gt; 你说的“能否放在赋值运算符左边”是一个非常好的启发式判断方法。一个更根本的、适用于现代 C++ 的区分标准是：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;我们能否对这个表达式“取地址”？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;左值 (lvalue)&lt;/strong&gt;：是一个&lt;strong&gt;表达式&lt;/strong&gt;，它指向了一个&lt;strong&gt;具名的、有持久状态的&lt;/strong&gt;对象或函数。我们可以&lt;strong&gt;对它取地址&lt;/strong&gt; (&lt;code&gt;&amp;amp;&lt;/code&gt;)。它在表达式结束后，依然存在。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;例子&lt;/strong&gt;：变量名 &lt;code&gt;int x;&lt;/code&gt; &lt;code&gt;x&lt;/code&gt; 是一个左值，我们可以 &lt;code&gt;&amp;amp;x&lt;/code&gt;。&lt;code&gt;std::string s;&lt;/code&gt; &lt;code&gt;s&lt;/code&gt; 是一个左值。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;右值 (rvalue)&lt;/strong&gt;：是一个&lt;strong&gt;表达式&lt;/strong&gt;，它通常代表一个&lt;strong&gt;匿名的、即将被销毁的临时值&lt;/strong&gt;。我们&lt;strong&gt;无法对它取地址&lt;/strong&gt;。它在表达式结束后，就不复存在了。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;例子&lt;/strong&gt;：字面量 &lt;code&gt;10&lt;/code&gt; 是一个右值，你不能 &lt;code&gt;&amp;amp;10&lt;/code&gt;。函数返回值 &lt;code&gt;get_string()&lt;/code&gt;（如果返回的是一个值而非引用）是一个右值。&lt;code&gt;x + y&lt;/code&gt; 这个表达式的结果也是一个右值。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;总结一下：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;左值&lt;/strong&gt;：有家（内存地址），能活得久。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;右值&lt;/strong&gt;：没家（没法取地址），是“过客”（马上就消失）。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="右值引用"&gt;右值引用&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;面试官 (引入新概念):&lt;/strong&gt; 好的，既然我们知道了左值和右值的区别。C++11 为了配合移动语义，引入了一种新的引用类型，叫做&lt;strong&gt;右值引用 (rvalue reference)&lt;/strong&gt;，用 &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 表示。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// x 是一个左值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;l_ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 左值引用 l_ref 绑定到左值 x (OK)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;r_ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 右值引用 r_ref 绑定到右值 20 (OK)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// int&amp;amp;&amp;amp; r_ref2 = x; // 错误！右值引用不能直接绑定到左值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;请问，&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 这个右值引用的主要设计目的是什么？它和我们之前讨论的&lt;strong&gt;移动语义 (Move Semantics)&lt;/strong&gt; 是如何关联起来的？&lt;/p&gt;</description></item><item><title>explicit关键字</title><link>https://Mist2233.github.io/posts/explicit%E5%85%B3%E9%94%AE%E5%AD%97/</link><pubDate>Sat, 12 Jul 2025 10:35:00 +0000</pubDate><guid>https://Mist2233.github.io/posts/explicit%E5%85%B3%E9%94%AE%E5%AD%97/</guid><description>&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;hr&gt;
&lt;h3 id="一问题根源什么是构造函数的隐式转换"&gt;一、问题根源：什么是构造函数的“隐式转换”？&lt;/h3&gt;
&lt;p&gt;在 C++ 中，编译器有时候会“自作主张”地帮你进行类型转换，让代码能够通过编译。如果一个类的&lt;strong&gt;构造函数可以只用一个参数来调用&lt;/strong&gt;，那么这个构造函数就可能被编译器用来进行&lt;strong&gt;隐式转换 (Implicit Conversion)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;让我们来看一个没有 &lt;code&gt;explicit&lt;/code&gt; 的“事故现场”：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;场景设定&lt;/strong&gt;：我们有一个字符串类 &lt;code&gt;MyString&lt;/code&gt;，它有一个构造函数，可以接受一个整数 &lt;code&gt;n&lt;/code&gt; 来创建一个由 &lt;code&gt;n&lt;/code&gt; 个 &lt;code&gt;'A'&lt;/code&gt; 组成的字符串。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyString&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;m_str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 这个构造函数可以用一个 int 参数来调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;MyString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;MyString(&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;) 被调用了！&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;c_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;m_str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_str&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 这是一个希望接收 MyString 对象的函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyString&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;打印: &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;现在，在 &lt;code&gt;main&lt;/code&gt; 函数中，我们可能会写出这样的代码：&lt;/p&gt;</description></item></channel></rss>