本書是一本C++進(jìn)階圖書,全書分為42章,深入探討了從C++11到C++20引入的核心特性。書中不僅通過(guò)大量的實(shí)例代碼講解特性的概念和語(yǔ)法,還從編譯器的角度分析特性的實(shí)現(xiàn)原理,書中還穿插了C++標(biāo)準(zhǔn)委員會(huì)制定特性標(biāo)準(zhǔn)時(shí)的一些小故事,幫助讀者知其然也知其所以然。
本書適合因?yàn)楣ぷ餍枰獙W(xué)習(xí)C++新特性的C++從業(yè)者,同樣也適合對(duì)C++新特性非常感興趣的C++愛(ài)好者。而對(duì)于C++初學(xué)者來(lái)說(shuō),也有必要在理解C++基礎(chǔ)知識(shí)后,通過(guò)本書來(lái)領(lǐng)略C++的另外一道風(fēng)景。
1.通過(guò)理論結(jié)合實(shí)踐的內(nèi)容編排,深入探討 C++11 到 C++20 引入的語(yǔ)言核心特性。
2.通過(guò)大量的實(shí)例代碼講解特性的概念和語(yǔ)法,并從編譯器的角度分析特性的實(shí)現(xiàn)原理。
3.本書提供作者的同步語(yǔ)音講解、PPT以及示例代碼等其它增值服務(wù)。
4.本書既能當(dāng)作一本教材讓讀者由淺入深掌握新增特性的原理和方法,也可作為一本“字典”讓讀者有目的性的查閱單個(gè)特性。
謝丙堃,從事 C++ 開(kāi)發(fā)工作十余年,先后在數(shù)家互聯(lián)網(wǎng)公司擔(dān)任 C++ 開(kāi)發(fā)工程師和技術(shù)經(jīng)理。他也是 C++ 語(yǔ)言的愛(ài)好者,熱衷于研究 C++ 語(yǔ)言的新特性以及 C++ 模板元編程技術(shù)。
第 1章 新基礎(chǔ)類型(C++11~C++20) 1
1.1 整數(shù)類型long long 1
1.2 新字符類型char16_t和char32_t 4
1.2.1 字符集和編碼方法 4
1.2.2 使用新字符類型char16_t和char32_t 5
1.2.3 wchar_t存在的問(wèn)題 6
1.2.4 新字符串連接 7
1.2.5 庫(kù)對(duì)新字符類型的支持 7
1.3 char8_t字符類型 8
1.4 總結(jié) 8
第 2章 內(nèi)聯(lián)和嵌套命名空間(C++11~C++20) 9
2.1 內(nèi)聯(lián)命名空間的定義和使用 9
2.2 嵌套命名空間的簡(jiǎn)化語(yǔ)法 11
2.3 總結(jié) 13
第3章 auto占位符(C++11~C++17) 14
3.1 重新定義的auto關(guān)鍵字 14
3.2 推導(dǎo)規(guī)則 16
3.3 什么時(shí)候使用auto 18
3.4 返回類型推導(dǎo) 20
3.5 lambda表達(dá)式中使用auto類型推導(dǎo) 20
3.6 非類型模板形參占位符 21
3.7 總結(jié) 22
第4章 decltype說(shuō)明符(C++11~C++17) 23
4.1 回顧typeof和typeid 23
4.2 使用decltype說(shuō)明符 24
4.3 推導(dǎo)規(guī)則 27
4.4 cv限定符的推導(dǎo) 29
4.5 decltype(auto) 30
4.6 decltype(auto)作為非類型模板形參占位符 31
4.7 總結(jié) 32
第5章 函數(shù)返回類型后置(C++11) 33
5.1 使用函數(shù)返回類型后置聲明函數(shù) 33
5.2 推導(dǎo)函數(shù)模板返回類型 34
5.3 總結(jié) 36
第6章 右值引用(C++11 C++17 C++20) 37
6.1 左值和右值 37
6.2 左值引用 39
6.3 右值引用 40
6.4 右值的性能優(yōu)化空間 42
6.5 移動(dòng)語(yǔ)義 43
6.6 值類別 47
6.7 將左值轉(zhuǎn)換為右值 48
6.8 萬(wàn)能引用和引用折疊 50
6.9 完美轉(zhuǎn)發(fā) 52
6.10 針對(duì)局部變量和右值引用的隱式移動(dòng)操作 55
6.11 總結(jié) 57
第7章 lambda表達(dá)式(C++11~C++20) 58
7.1 lambda表達(dá)式語(yǔ)法 58
7.2 捕獲列表 60
7.2.1 作用域 60
7.2.2 捕獲值和捕獲引用 61
7.2.3 特殊的捕獲方法 64
7.3 lambda表達(dá)式的實(shí)現(xiàn)原理 65
7.4 無(wú)狀態(tài)lambda表達(dá)式 68
7.5 在STL中使用lambda表達(dá)式 68
7.6 廣義捕獲 69
7.7 泛型lambda表達(dá)式 72
7.8 常量lambda表達(dá)式和捕獲*this 72
7.9 捕獲[=, this] 73
7.10 模板語(yǔ)法的泛型lambda表達(dá)式 74
7.11 可構(gòu)造和可賦值的無(wú)狀態(tài)lambda表達(dá)式 76
7.12 總結(jié) 77
第8章 非靜態(tài)數(shù)據(jù)成員默認(rèn)初始化(C++11 C++20) 78
8.1 使用默認(rèn)初始化 78
8.2 位域的默認(rèn)初始化 79
8.3 總結(jié) 80
第9章 列表初始化(C++11 C++20) 81
9.1 回顧變量初始化 81
9.2 使用列表初始化 82
9.3 std::initializer_list詳解 84
9.4 使用列表初始化的注意事項(xiàng) 86
9.4.1 隱式縮窄轉(zhuǎn)換問(wèn)題 86
9.4.2 列表初始化的優(yōu)先級(jí)問(wèn)題 87
9.5 指定初始化 88
9.6 總結(jié) 90
第 10章 默認(rèn)和刪除函數(shù)(C++11) 91
10.1 類的特殊成員函數(shù) 91
10.2 顯式默認(rèn)和顯式刪除 95
10.3 顯式刪除的其他用法 98
10.4 explicit和=delete 99
10.5 總結(jié) 100
第 11章 非受限聯(lián)合類型(C++11) 101
11.1 聯(lián)合類型在C++中的局限性 101
11.2 使用非受限聯(lián)合類型 102
11.3 總結(jié) 106
第 12章 委托構(gòu)造函數(shù)(C++11) 107
12.1 冗余的構(gòu)造函數(shù) 107
12.2 委托構(gòu)造函數(shù) 110
12.3 委托模板構(gòu)造函數(shù) 114
12.4 捕獲委托構(gòu)造函數(shù)的異常 115
12.5 委托參數(shù)較少的構(gòu)造函數(shù) 116
12.6 總結(jié) 117
第 13章 繼承構(gòu)造函數(shù)(C++11) 118
13.1 繼承關(guān)系中構(gòu)造函數(shù)的困局 118
13.2 使用繼承構(gòu)造函數(shù) 119
13.3 總結(jié) 123
第 14章 強(qiáng)枚舉類型(C++11 C++17 C++20) 124
14.1 枚舉類型的弊端 124
14.2 使用強(qiáng)枚舉類型 129
14.3 列表初始化有底層類型枚舉對(duì)象 131
14.4 使用using打開(kāi)強(qiáng)枚舉類型 133
14.5 總結(jié) 135
第 15章 擴(kuò)展的聚合類型(C++17 C++20) 136
15.1 聚合類型的新定義 136
15.2 聚合類型的初始化 137
15.3 擴(kuò)展聚合類型的兼容問(wèn)題 139
15.4 禁止聚合類型使用用戶聲明的構(gòu)造函數(shù) 140
15.5 使用帶小括號(hào)的列表初始化聚合類型對(duì)象 142
15.6 總結(jié) 143
第 16章 override和final說(shuō)明符(C++11) 144
16.1 重寫、重載和隱藏 144
16.2 重寫引發(fā)的問(wèn)題 145
16.3 使用override說(shuō)明符 145
16.4 使用final說(shuō)明符 146
16.5 override和final說(shuō)明符的特別之處 148
16.6 總結(jié) 148
第 17章 基于范圍的for循環(huán)(C++11 C++17 C++20) 149
17.1 煩瑣的容器遍歷 149
17.2 基于范圍的for循環(huán)語(yǔ)法 150
17.3 begin和end函數(shù)不必返回相同類型 151
17.4 臨時(shí)范圍表達(dá)式的陷阱 152
17.5 實(shí)現(xiàn)一個(gè)支持基于范圍的for循環(huán)的類 153
17.6 總結(jié) 155
第 18章 支持初始化語(yǔ)句的if和switch(C++17) 156
18.1 支持初始化語(yǔ)句的if 156
18.2 支持初始化語(yǔ)句的switch 159
18.3 總結(jié) 160
第 19章 static_assert聲明 161
19.1 運(yùn)行時(shí)斷言 161
19.2 靜態(tài)斷言的需求 162
19.3 靜態(tài)斷言 163
19.4 單參數(shù)static_assert 164
19.5 總結(jié) 165
第 20章 結(jié)構(gòu)化綁定(C++17 C++20) 166
20.1 使用結(jié)構(gòu)化綁定 166
20.2 深入理解結(jié)構(gòu)化綁定 169
20.3 結(jié)構(gòu)化綁定的3種類型 171
20.3.1 綁定到原生數(shù)組 171
20.3.2 綁定到結(jié)構(gòu)體和類對(duì)象 172
20.3.3 綁定到元組和類元組的對(duì)象 173
20.4 實(shí)現(xiàn)一個(gè)類元組類型 175
20.5 綁定的訪問(wèn)權(quán)限問(wèn)題 178
20.6 總結(jié) 179
第 21章 noexcept關(guān)鍵字(C++11 C++17 C++20) 180
21.1 使用noexcept代替throw 180
21.2 用noexcept來(lái)解決移動(dòng)構(gòu)造問(wèn)題 183
21.3 noexcept和throw() 185
21.4 默認(rèn)使用noexcept的函數(shù) 186
21.5 使用noexcept的時(shí)機(jī) 189
21.6 將異常規(guī)范作為類型的一部分 190
21.7 總結(jié) 192
第 22章 類型別名和別名模板(C++11 C++14) 193
22.1 類型別名 193
22.2 別名模板 194
22.3 總結(jié) 196
第 23章 指針字面量nullptr(C++11) 197
23.1 零值整數(shù)字面量 197
23.2 nullptr關(guān)鍵字 198
23.3 總結(jié) 201
第 24章 三向比較(C++20) 202
24.1 “太空飛船”(spaceship)運(yùn)算符 202
24.2 三向比較的返回類型 202
24.2.1 std::strong_ordering 203
24.2.2 std::weak_ordering 204
24.2.3 std::partial_ordering 205
24.3 對(duì)基礎(chǔ)類型的支持 206
24.4 自動(dòng)生成的比較運(yùn)算符函數(shù) 207
24.5 兼容舊代碼 210
24.6 總結(jié) 211
第 25章 線程局部存儲(chǔ)(C++11) 212
25.1 操作系統(tǒng)和編譯器對(duì)線程局部存儲(chǔ)的支持 212
25.2 thread_local說(shuō)明符 213
25.3 總結(jié) 217
第 26章 擴(kuò)展的inline說(shuō)明符(C++17) 218
26.1 定義非常量靜態(tài)成員變量的問(wèn)題 218
26.2 使用inline說(shuō)明符 219
26.3 總結(jié) 220
第 27章 常量表達(dá)式(C++11~C++20) 221
27.1 常量的不確定性 221
27.2 constexpr值 224
27.3 constexpr函數(shù) 225
27.4 constexpr構(gòu)造函數(shù) 228
27.5 對(duì)浮點(diǎn)的支持 230
27.6 C++14標(biāo)準(zhǔn)對(duì)常量表達(dá)式函數(shù)的增強(qiáng) 230
27.7 constexpr lambdas表達(dá)式 233
27.8 constexpr的內(nèi)聯(lián)屬性 235
27.9 if constexpr 236
27.10 允許constexpr虛函數(shù) 240
27.11 允許在constexpr函數(shù)中出現(xiàn)Try-catch 244
27.12 允許在constexpr中進(jìn)行平凡的默認(rèn)初始化 244
27.13 允許在constexpr中更改聯(lián)合類型的有效成員 245
27.14 使用consteval聲明立即函數(shù) 246
27.15 使用constinit檢查常量初始化 247
27.16 判斷常量求值環(huán)境 248
27.17 總結(jié) 252
第 28章 確定的表達(dá)式求值順序(C++17) 253
28.1 表達(dá)式求值順序的不確定性 253
28.2 表達(dá)式求值順序詳解 254
28.3 總結(jié) 255
第 29章 字面量?jī)?yōu)化(C++11~C++17) 257
29.1 十六進(jìn)制浮點(diǎn)字面量 257
29.2 二進(jìn)制整數(shù)字面量 258
29.3 單引號(hào)作為整數(shù)分隔符 258
29.4 原生字符串字面量 259
29.5 用戶自定義字面量 261
29.6 總結(jié) 267
第30章 alignas和alignof(C++11 C++17) 268
30.1 不可忽視的數(shù)據(jù)對(duì)齊問(wèn)題 268
30.2 C++11標(biāo)準(zhǔn)之前控制數(shù)據(jù)對(duì)齊的方法 270
30.3 使用alignof運(yùn)算符 272
30.4 使用alignas說(shuō)明符 273
30.5 其他關(guān)于對(duì)齊字節(jié)長(zhǎng)度的支持 276
30.6 C++17中使用new分配指定對(duì)齊字節(jié)長(zhǎng)度的對(duì)象 278
30.7 總結(jié) 279
第31章 屬性說(shuō)明符和標(biāo)準(zhǔn)屬性(C++11~C++20) 280
31.1 GCC的屬性語(yǔ)法 280
31.2 MSVC的屬性語(yǔ)法 281
31.3 標(biāo)準(zhǔn)屬性說(shuō)明符語(yǔ)法 282
31.4 使用using打開(kāi)屬性的命名空間 283
31.5 標(biāo)準(zhǔn)屬性 283
31.5.1 noreturn 284
31.5.2 carries_dependency 286
31.5.3 deprecated 286
31.5.4 fallthrough 287
31.5.5 nodiscard 288
31.5.6 maybe_unused 290
31.5.7 likely和unlikely 290
31.5.8 no_unique_address 291
31.6 總結(jié) 293
第32章 新增預(yù)處理器和宏(C++17 C++20) 294
32.1 預(yù)處理器__has_include 294
32.2 特性測(cè)試宏 295
32.2.1 屬性特性測(cè)試宏 295
32.2.2 語(yǔ)言功能特性測(cè)試宏 295
32.2.3 標(biāo)準(zhǔn)庫(kù)功能特性測(cè)試宏 297
32.3 新增宏__VA_OPT__ 301
32.4 總結(jié) 302
第33章 協(xié)程(C++20) 303
33.1 協(xié)程的使用方法 303
33.2 協(xié)程的實(shí)現(xiàn)原理 308
33.2.1 co_await運(yùn)算符原理 308
33.2.2 co_yield運(yùn)算符原理 313
33.2.3 co_return運(yùn)算符原理 317
33.2.4 promise_type的其他功能 319
33.3 總結(jié) 320
第34章 基礎(chǔ)特性的其他優(yōu)化(C++11~C++20) 321
34.1 顯式自定義類型轉(zhuǎn)換運(yùn)算符(C++11) 321
34.2 關(guān)于std::launder()(C++17) 325
34.3 返回值優(yōu)化(C++11~C++17) 326
34.4 允許按值進(jìn)行默認(rèn)比較(C++20) 333
34.5 支持new表達(dá)式推導(dǎo)數(shù)組長(zhǎng)度(C++20) 334
34.6 允許數(shù)組轉(zhuǎn)換為未知范圍的數(shù)組(C++20) 335
34.7 在delete運(yùn)算符函數(shù)中析構(gòu)對(duì)象(C++20) 336
34.8 調(diào)用偽析構(gòu)函數(shù)結(jié)束對(duì)象聲明周期(C++20) 337
34.9 修復(fù)const和默認(rèn)復(fù)制構(gòu)造函數(shù)不匹配造成無(wú)法編譯的問(wèn)題
(C++20) 338
34.10 不推薦使用volatile的情況(C++20) 339
34.11 不推薦在下標(biāo)表達(dá)式中使用逗號(hào)運(yùn)算符(C++20) 340
34.12 模塊(C++20) 340
34.13 總結(jié) 341
第35章 可變參數(shù)模板(C++11 C++17 C++20) 342
35.1 可變參數(shù)模板的概念和語(yǔ)法 342
35.2 形參包展開(kāi) 344
35.3 sizeof...運(yùn)算符 352
35.4 可變參數(shù)模板的遞歸計(jì)算 353
35.5 折疊表達(dá)式 354
35.6 一元折疊表達(dá)式中空參數(shù)包的特殊處理 357
35.7 using聲明中的包展開(kāi) 358
35.8 lambda表達(dá)式初始化捕獲的包展開(kāi) 359
35.9 總結(jié) 361
第36章 typename優(yōu)化(C++17 C++20) 362
36.1 允許使用typename聲明模板形參 362
36.2 減少typename使用的必要性 363
36.3 總結(jié) 365
第37章 模板參數(shù)優(yōu)化(C++11 C++17 C++20) 366
37.1 允許常量求值作為所有非類型模板的實(shí)參 366
37.2 允許局部和匿名類型作為模板實(shí)參 368
37.3 允許函數(shù)模板的默認(rèn)模板參數(shù) 369
37.4 函數(shù)模板添加到ADL查找規(guī)則 370
37.5 允許非類型模板形參中的字面量類類型 371
37.6 擴(kuò)展的模板參數(shù)匹配規(guī)則 373
37.7 總結(jié) 374
第38章 類模板的模板實(shí)參推導(dǎo)(C++17 C++20) 375
38.1 通過(guò)初始化構(gòu)造推導(dǎo)類模板的模板實(shí)參 375
38.2 拷貝初始化優(yōu)先 377
38.3 lambda類型的用途 378
38.4 別名模板的類模板實(shí)參推導(dǎo) 380
38.5 聚合類型的類模板實(shí)參推導(dǎo) 380
38.6 總結(jié) 382
第39章 用戶自定義推導(dǎo)指引(C++17) 383
39.1 使用自定義推導(dǎo)指引推導(dǎo)模板實(shí)例 383
39.2 聚合類型類模板的推導(dǎo)指引 386
39.3 總結(jié) 387
第40章 SFINAE(C++11) 388
40.1 替換失敗和編譯錯(cuò)誤 388
40.2 SFINAE規(guī)則詳解 389
40.3 總結(jié) 394
第41章 概念和約束(C++20) 395
41.1 使用std::enable_if約束模板 395
41.2 概念的背景介紹 396
41.3 使用concept和約束表達(dá)式定義概念 397
41.4 requires子句和約束檢查順序 398
41.5 原子約束 401
41.6 requires表達(dá)式 403
41.6.1 簡(jiǎn)單要求 404
41.6.2 類型要求 405
41.6.3 復(fù)合要求 405
41.6.4 嵌套要求 406
41.7 約束可變參數(shù)模板 407
41.8 約束類模板特化 408
41.9 約束auto 409
41.10 總結(jié) 410
第42章 模板特性的其他優(yōu)化(C++11 C++14) 411
42.1 外部模板(C++11) 411
42.2 連續(xù)右尖括號(hào)的解析優(yōu)化(C++11) 413
42.3 friend聲明模板形參(C++11) 415
42.4 變量模板(C++14) 417
42.5 explicit(bool) 419
42.6 總結(jié) 423
附錄 特性章節(jié)對(duì)照表 424