@@ -421,7 +421,7 @@ <h2 id="index-_1">前言</h2>
421
421
<blockquote>
422
422
<p><img src="../img/bulb.png" height="30px" width="auto" style="margin: 0; border: none"/> 本书还在持续更新中……要追番的话,可以在 <a href="https://github.com/parallel101/cppguidebook">GitHub</a> 点一下右上角的 “Watch” 按钮,每当小彭老师提交新 commit,GitHub 会向你发送一封电子邮件,提醒你小彭老师更新了。</p>
423
423
</blockquote>
424
- <p>更新时间:2024年11月01日 12:54:16 (UTC+08:00)</p>
424
+ <p>更新时间:2024年11月09日 11:37:54 (UTC+08:00)</p>
425
425
<p><a href="https://parallel101.github.io/cppguidebook">在 GitHub Pages 浏览本书</a> | <a href="https://142857.red/book">在小彭老师自己维护的镜像上浏览本书</a></p>
426
426
<h2 id="index-_2">格式约定</h2>
427
427
<blockquote>
@@ -941,31 +941,31 @@ <h2 id="auto-auto_2">返回类型 <code>auto</code></h2>
941
941
<p><img src="../img/awesomeface.png" height="30px" width="auto" style="margin: 0; border: none"/> 闹了半天,还是要写返回类型,就只是挪到后面去好看一点……</p>
942
942
<p><img src="../img/question.png" height="30px" width="auto" style="margin: 0; border: none"/> 当初引入后置返回类型实际的用途是 <code>auto f(int x) -> decltype(x * x) { return x * x; }</code> 这种情况,但很容易被接下来 C++14 引入的真正 <code>auto</code> 返回类型推导平替了。</p>
943
943
</blockquote>
944
- <p>C++14 引入了函数<strong>返回类型推导</strong>,<code>auto</code> 才算真正意义上能用做函数返回类型,它会自动根据函数中的 <code>return</code> 表达式推导出函数的返回类型。</p>
944
+ <p>但是 C++14 引入了函数<strong>返回类型推导</strong>,<code>auto</code> 才算真正意义上能用做函数返回类型,它会自动根据函数中的 <code>return</code> 表达式推导出函数的返回类型。</p>
945
945
<pre><code class="language-cpp">auto f(int x) {
946
- return x * x; // 表达式 `x * x` 的类型为 int,所以 auto 类型推导为 int
946
+ return x * x; // 表达式 `x * x` 的类型为 int,所以 auto 类型推导为 int
947
947
}
948
948
// 等价于:
949
949
int f() {
950
- return x * x;
950
+ return x * x;
951
951
}
952
952
</code></pre>
953
953
<p>如果函数中没有 <code>return</code> 语句,那么 <code>auto</code> 会被自动推导为 <code>void</code>,非常方便。</p>
954
954
<pre><code class="language-cpp">auto f() {
955
- std::println("hello");
955
+ std::println("hello");
956
956
}
957
957
// 等价于:
958
958
void f() {
959
- std::println("hello");
959
+ std::println("hello");
960
960
}
961
961
</code></pre>
962
962
<p>值得注意的是,返回类型用 <code>auto</code> 来推导的函数,如果有多条 <code>return</code> 语句,那么他们必须都返回相同的类型,否则报错。</p>
963
963
<pre><code class="language-cpp">auto f(int x) {
964
- if (x > 0) {
965
- return 1; // int
966
- } else {
967
- return 3.14; // double
968
- }
964
+ if (x > 0) {
965
+ return 1; // int
966
+ } else {
967
+ return 3.14; // double
968
+ }
969
969
} // 错误:有歧义,无法确定 auto 应该推导为 int 还是 double
970
970
</code></pre>
971
971
<p><code>auto</code> 还有一个缺点是,无法用于“分离声明和定义”的情况。因为推导 <code>auto</code> 类型需要知道函数体,才能看到里面的 <code>return</code> 表达式是什么类型。所以当 <code>auto</code> 返回类型被用于函数的非定义声明时,会直接报错。</p>
@@ -978,7 +978,41 @@ <h2 id="auto-auto_2">返回类型 <code>auto</code></h2>
978
978
<p>因此,<code>auto</code> 通常只适用于头文件中“就地定义”的 <code>inline</code> 函数,不适合需要“分离 .cpp 文件”的函数。</p>
979
979
<h2 id="auto-auto_3">参数类型 <code>auto</code></h2>
980
980
<p>C++20 引入了<strong>模板参数推导</strong>,可以让我们在函数参数中也使用 <code>auto</code>。</p>
981
- <p>TODO: 介绍</p>
981
+ <p>在函数参数中也使用 <code>auto</code> 实际上等价于将该参数声明为模板参数,仅仅是一种更便捷的写法。</p>
982
+ <pre><code class="language-cpp">void func(auto x) {
983
+ std::cout << x;
984
+ }
985
+ // 等价于:
986
+ template <typename T>
987
+ void func(T x) {
988
+ std::cout << x;
989
+ }
990
+
991
+ func(1); // 自动推导为调用 func<int>(1)
992
+ func(3.14); // 自动推导为调用 func<double>(3.14)
993
+ </code></pre>
994
+ <p>如果参数类型的 <code>auto</code> 带有如 <code>auto &</code> 这样的修饰,则实际上等价于相应模板函数的 <code>T &</code>。</p>
995
+ <pre><code class="language-cpp">// 自动推导为常引用
996
+ void func(auto const &x) {
997
+ std::cout << x;
998
+ }
999
+ // 等价于:
1000
+ template <typename T>
1001
+ void func(T const &x) {
1002
+ std::cout << x;
1003
+ }
1004
+
1005
+ // 自动推导为万能引用
1006
+ void func(auto &&x) {
1007
+ std::cout << x;
1008
+ }
1009
+ // 等价于:
1010
+ template <typename T>
1011
+ void func(T &&x) {
1012
+ std::cout << x;
1013
+ }
1014
+ </code></pre>
1015
+ <h3 id="auto-auto_4"><code>auto</code> 在多态中的妙用</h3>
982
1016
<p>传统的,基于类型重载的:</p>
983
1017
<pre><code class="language-cpp">int square(int x) {
984
1018
return x * x;
@@ -1005,7 +1039,7 @@ <h2 id="auto-auto_3">参数类型 <code>auto</code></h2>
1005
1039
// 即使未来产生了 float 版的需求,也不用添加任何代码,因为是 square 是很方便的模板函数
1006
1040
}
1007
1041
</code></pre>
1008
- <h2 id="auto-auto_4 "><code>auto</code> 推导为引用</h2>
1042
+ <h2 id="auto-auto_5 "><code>auto</code> 推导为引用</h2>
1009
1043
<p>TODO: 继续介绍 <code>auto</code>, <code>auto const</code>, <code>auto &</code>, <code>auto const &</code>, <code>auto &&</code>, <code>decltype(auto)</code>, <code>auto *</code>, <code>auto const *</code></p></section><section class="print-page" id="symbols"><h1 id="symbols-_1">重新认识声明与定义(未完工)</h1>
1010
1044
<div class="toc">
1011
1045
<ul>
0 commit comments