學習 C++20 (中文版) C++20 for Programmers: An Objects-Natural Approach

[美]保羅·J.戴特爾(Paul J. Deitel)[美] 哈維·M.戴特爾(Harvey M. Deitel)著 周靖 譯

  • 學習 C++20 (中文版)-preview-1
  • 學習 C++20 (中文版)-preview-2
  • 學習 C++20 (中文版)-preview-3
學習 C++20 (中文版)-preview-1

買這商品的人也買了...

商品描述

《學習C++20(中文版)》共18章5個附錄,討論了C++20的5大編程模型:程序化編程、函數式編程、面向對象編程、泛型編程和模板元編程。第I部分介紹基礎知識,第II部分介紹容器、C++20範圍、指針、字符串和文件,第III部分介紹現代面向對象編程和異常,第Ⅳ部分介紹泛型編程、模板、概念和模板元編程,第V部分介紹高級主題,包括模塊、並行算法、並發和協程。 《學習C++20(中文版)》適合需要瞭解C++20新特性的程序員,包括零基礎或有經驗的C++程序員以及其他想要瞭解C++的程序員,也適合希望開課教C++20的老師。

目錄大綱

簡明目錄

第Ⅰ部分 編程基礎

第1章 免費、流行的C++編譯器 003

第2章 C++編程入門 025

第3章 控制語句(上) 045

第4章 控制語句(下) 077

第5章 函數和函數模板入門 113

第Ⅱ部分 數組、指針和字符串

第6章 數組、向量、範圍和函數式編程 171

第7章 現代C++對指針的淡化 211

第8章 string、string_view、文本文件、CSV文件和正則表達式 247

第Ⅲ部分 面向對象程序設計

第9章 自定義類 303

第10章 OOP:繼承和運行時多態性 379

第11章 操作符重載、拷貝/移動語義和智能指針 467

第12章 異常和對契約的展望 527

第Ⅳ部分 標準庫容器、迭代器和算法

第13章 標準庫容器和迭代器 571

第14章 標準庫算法和C++20範圍/視圖 625

第Ⅴ部分 高級編程主題

第15章 模板、C++20“概念”和元編程 703

第16章 C++20模塊:大規模開發 797

第17章 並行算法和並發性:高級觀點 851

第18章 C++20協程 994

附錄A 操作符優先級和分組 969

附錄B 字符集 971

 

詳細目錄

第Ⅰ部分 編程基礎

第1章 免費、流行的C++編譯器

1.1 導讀 004

1.2 試運行一個C++20應用程序 005

1.2.1 在Windows上用VS 2022社區版編譯和運行C++20應用程序 005

1.2.2 在macOS上用Xcode編譯和運行C++20應用程序 009

1.2.3 在Linux上用GNU C++運行C++20應用程序 013

1.2.4 在GCC Docker容器中編譯和運行C++20應用程序 015

1.2.5 在Docker容器中使用clang++來編譯和運行C++20應用程序 016

1.3 摩爾定律、多核處理器和並發編程 018

1.4 面向對象簡單回顧 019

1.5 小結 021

第2章 C++編程入門

2.1 導讀 026

2.2 第一個C++程序:顯示單行文本 026

2.3 修改第一個C++程序 030

2.4 另一個C++程序:整數相加 031

2.5 算術運算 035

2.6 決策:相等性和關系操作符 036

2.7 對象自然案例學習:創建和使用標準庫類string的對象 040

2.8 小結 044

第3章 控制語句(上)

3.1 導讀 046

3.2 控制結構 046

3.2.1 順序結構 046

3.2.2 選擇語句 047

3.2.3 循環語句 048

3.2.4 控制語句小結 049

3.3 if選擇語句 049

3.4 if…else雙選語句 050

3.4.1 嵌套if…else語句 051

3.4.2 代碼塊 052

3.4.3 條件操作符( :) 053

3.5 while循環語句 053

3.6 計數器控制的循環 054

3.6.1 實現計數器控制的循環 054

3.6.2 整數除法和截斷 056

3.7 哨兵值控制的循環 056

3.7.1 實現哨兵值控制的循環 057

3.7.2 基礎類型之間的顯式和隱式轉換 059

3.7.3 格式化浮點數 060

3.8 嵌套控制語句 061

3.8.1 問題陳述 061

3.8.2 實現程序 062

3.8.3 用大括號初始化防止收縮轉換 064

3.9 復合賦值操作符 065

3.10 遞增和遞減操作符 065

3.11 基本類型不可移植 068

3.12 對象自然案例學習:任意大小的整數 068

3.13 C++20:用format函數格式化文本 073

3.14 小結 075

第4章 控制語句(下)

4.1 導讀 078

4.2 計數器控制的循環的本質 078

4.3 for循環語句 079

4.4 for循環的例子 081

4.5 應用程序:累加偶數整數 082

4.6 應用程序:復利計算 083

4.7 do…while循環語句 087

4.8 switch多選語句 088

4.9 使用帶初始化器的C++17選擇語句 094

4.10 break語句和continue語句 095

4.11 邏輯操作符 097

4.11.1 邏輯AND(&&)操作符 098

4.11.2 邏輯OR(||)操作符 098

4.11.3 短路求值 099

4.11.4 邏輯非(!)操作符 099

4.11.5 示例:生成邏輯操作符真值表 100

4.12 混淆相等性(==)和賦值(=)操作符 102

4.13 對象自然案例學習:使用miniz-cpp庫讀寫ZIP文件8 103

4.14 用域寬和精度進行C++20文本格式化 108

4.15 小結 110

第5章 函數和函數模板入門

5.1 導讀 114

5.2 C++程序組件 114

5.3 數學庫函數 115

5.4 函數定義和函數原型 117

5.5 函數實參的求值順序 120

5.6 函數原型和實參強制類型轉換的有關註意事項 120

5.6.1 函數簽名和函數原型 121

5.6.2 實參強制類型轉換 121

5.6.3 實參提升規則和隱式轉換 121

5.7 C++標準庫頭文件 123

5.8 案例學習:隨機數生成 126

5.8.1 擲六面骰子 127

5.8.2 六面骰子擲6000萬次 127

5.8.3 為給隨機數生成器提供種子 129

5.8.4 用random_device為隨機數生成器提供種子 131

5.9 案例學習:概率游戲,介紹有作用域的enum  131

5.10 作用域規則 137

5.11 內聯函數 142

5.12 引用和引用參數 143

5.13 默認參數 146

5.14 一元作用域解析操作符 147

5.15 函數重載 148

5.16 函數模板 152

5.17 遞歸 155

5.18 遞歸示例:斐波那契數列 158

5.19 對比遞歸和循環 161

5.20 Lnfylun Lhqtomh Wjtz Qarcv: Qjwazkrplm xzz Xndmwwqhlz 163

5.21 小結 166

第Ⅱ部分 數組、指針和字符串

第6章 數組、向量、範圍和函數式編程

6.1 導讀 172

6.2 數組 172

6.3 聲明數組 173

6.4 用循環初始化數組元素 173

6.5 用初始化器列表初始化數組 176

6.6 C++11基於範圍的for和C++20帶初始化器的基於範圍的for 177

6.7 計算數組元素值並理解constexpr 180

6.8 累加數組元素 182

6.9 使用簡陋的條形圖以圖形方式顯示數組數據 182

6.10 數組元素作為計數器使用 184

6.11 使用數組來匯總調查結果 186

6.12 數組排序和查找 187

6.13 多維數組 189

6.14 函數式編程入門 194

6.14.1 做什麽和怎麽做 194

6.14.2 函數作為實參傳給其他函數:理解lambda表達式 195

6.14.3 過濾器、映射和歸約:理解C++20的“範圍”庫 197

6.15 對象自然案例學習:C++標準庫類模板vector 201

6.16 小結 208

第7章 現代C++對指針的淡化

7.1 導讀 212

7.2 聲明和初始化指針變量 213

7.2.1 聲明指針 214

7.2.2 初始化指針 214

7.2.3 C++11之前的空指針 214

7.3 指針操作符 214

7.3.1 取址(&)操作符 215

7.3.2 間接尋址(*)操作符 215

7.3.3 使用取址(&)和間接尋址(*)操作符 216

7.4 用指針傳引用 217

7.5 內置數組 221

7.5.1 聲明和訪問內置數組 222

7.5.2 初始化內建數組 222

7.5.3 向函數傳遞內置數組 222

7.5.4 聲明內置數組參數 223

7.5.5 C++11標準庫函數begin和end 223

7.5.6 內置數組的限制 223

7.6 使用C++20 to_array將內置數組轉換成std::array 224

7.7 為指針和它指向的數據使用const 225

7.7.1 指向非常量數據的非常量指針 226

7.7.2 指向常量數據的非常量指針 226

7.7.3 指向非常量數據的常量指針 227

7.7.4 指向常量數據的常量指針 228

7.8 sizeof操作符 229

7.9 指針表達式和指針算術 232

7.9.1 在指針上加減整數 232

7.9.2 從指針上減一個指針 233

7.9.3 指針賦值 234

7.9.4 不能解引用void* 234

7.9.5 指針比較 234

7.10 對象自然案例學習:C++20 span,連續容器元素的視圖 234

7.11 理解基於指針的字符串 240

7.11.1 命令行參數 242

7.11.2 再論C++20的to_array函數 243

7.12 展望其他指針主題 244

7.13 小結 245

第8章 string、string_view、文本文件、CSV文件和正則表達式

8.1 導讀 248

8.2 字符串賦值和連接 249

8.3 字符串比較 251

8.4 子串 253

8.5 交換字符串 254

8.6 收集string特徵信息 254

8.7 在字符串中查找子串和字符 257

8.8 替換和刪除字符串中的字符 260

8.9 在字符串中插入字符 262

8.10 C++11數值轉換 263

8.11 C++17 string_view 264

8.12 文件和流 267

8.13 創建順序文件 268

8.14 從順序文件讀取數據 271

8.15 C++14讀取和寫入引號文本 274

8.16 更新順序文件 275

8.17 字符串流處理 276

8.18 原始字符串字面值 279

8.19 對象自然案例學習:讀取和分析包含泰坦尼克號災難數據的CSV文件 280

8.19.1 使用 rapidcsv 讀取 CSV 文件的內容 280

8.19.2 讀取和分析泰坦尼克號災難數據集 282

8.20 對象自然案例學習:理解正則表達式 290

8.20.1 將完整字符串與模式相匹配 291

8.20.2 替換子串 296

8.20.3 查找匹配 296

8.21 小結 299

第Ⅲ部分 面向對象程序設計

第9章 自定義類

9.1 導讀 304

9.2 體驗Account對象 304

9.3 具有賦值和取值成員函數的Account類 306

9.3.1 類定義 306

9.3.2 訪問說明符private和public 309

9.4 Account類:自定義構造函數 309

9.5 賦值和取值成員函數的軟件工程優勢 313

9.6 含有餘額的Account類 314

9.7 Time類案例學習:分離接口與實現 318

9.7.1 類的接口 319

9.7.2 分離接口與實現 319

9.7.3 類定義 320

9.7.4 成員函數 321

9.7.5 在源代碼文件中包含類的頭文件 322

9.7.6 作用域解析操作符(::) 322

9.7.7 成員函數setTime和拋出異常 323

9.7.8 成員函數to24HourString和to12HourString 323

9.7.9 隱式內聯的成員函數 324

9.7.10 成員函數與全局函數 324

9.7.11 使用Time類 324

9.7.12 對象的大小 326

9.8 編譯和鏈接過程 326

9.9 類作用域以及對類成員的訪問 327

9.10 訪問函數和實用函數 328

9.11 Time類案例學習:帶有默認參數的構造函數 329

9.11.1 Time類 329

9.11.2 重載構造函數和C++11委托構造函數 334

9.12 析構函數 335

9.13 什麽時候調用構造函數和析構函數 335

9.14 Time類案例學習:返回到private數據成員的引用或指針時,須謹慎 339

9.15 默認賦值操作符 342

9.16 const對象和const成員函數 344

9.17 合成:對象作為類成員 346

9.18 友元函數和友元類 351

9.19 this指針 353

9.19.1 隱式和顯式使用this指針訪問對象的數據成員 354

9.19.2 使用this指針來實現級聯函數調用 355

9.20 靜態類成員:類級數據和成員函數 359

9.21 C++20中的聚合 364

9.21.1 初始化聚合 365

9.21.2 C++20:指定初始化器 365

9.22 對象自然案例學習:用JSON序列化 366

9.22.1 序列化由包含public數據的對象構成的vector 367

9.22.2 序列化由包含private數據的對象構成的vector 372

9.23 小結 374

第10章 OOP:繼承和運行時多態性

10.1 導讀 380

10.2 基類和派生類 382

10.2.1 CommunityMember類層次結構 383

10.2.2 Shape類層次結構和public繼承 384

10.3 基類和派生類的關系 385

10.3.1 創建和使用SalariedEmployee類 385

10.3.2 創建SalariedEmployee/SalariedCommissionEmployee繼承層次結構 388

10.4 派生類中的構造函數和析構函數 394

10.5 運行時多態性入門:多態性電子游戲 395

10.6 繼承層次結構中對象之間的關系 396

10.6.1 從派生類對象調用基類函數 397

10.6.2 派生類指針指向基類對象 400

10.6.3 通過基類指針調用派生類成員函數 401

10.7 虛函數和虛析構函數 403

10.7.1 為什麽虛函數這麽有用? 403

10.7.2 聲明虛函數 403

10.7.3 調用虛函數 403

10.7.4 SalariedEmployee層次結構中的虛函數 404

10.7.5 虛析構函數 408

10.7.6 final成員函數和類 408

10.8 抽象類和純虛函數 409

10.8.1 純虛函數 409

10.8.2 設備驅動程序:操作系統中的多態性 410

10.9 案例學習:使用運行時多態性的薪資系統 410

10.9.1 創建抽象基類Employee 411

10.9.2 創建派生的具體類SalariedEmployee 414

10.9.3 創建派生的具體類CommissionEmployee 416

10.9.4 演示運行時多態性處理 418

10.10 運行時多態性、虛函數和動態綁定的幕後機制 421

10.11 非虛接口(NVI)慣用法 425

10.12 藉由接口來編程,而不要藉由實現26 432

10.12.1 重新思考Employee層次結構:CompensationModel接口 434

10.12.2 Employee類 434

10.12.3 實現CompensationModel 436

10.12.4 測試新層次結構 439

10.12.5 依賴註入在設計上的優勢 440

10.13 使用std::variant和std::visit實現運行時多態性 441

10.14 多繼承 447

10.14.1 菱形繼承 452

10.14.2 用虛基類繼承消除重復的子對象 454

10.15 深入理解protected類成員 456

10.16 public、protected和private繼承 457

10.17 更多運行時多態性技術和編譯時多態性 458

10.17.1 其他運行時多態性技術 458

10.17.2 編譯時(靜態)多態性技術 460

10.17.3 其他多態性概念 461

10.18 小結 461

第11章 操作符重載、拷貝/移動語義和智能指針

11.1 導讀 468

11.2 使用標準庫string類的重載操作符 470

11.3 操作符重載基礎 476

11.3.1 操作符不會自動重載 476

11.3.2 不能重載的操作符 476

11.3.3 不必重載的操作符 476

11.3.4 操作符重載的規則和限制 477

11.4 用new和delete進行動態內存管理(過時技術) 477

11.5 現代C++動態內存管理:RAII和智能指針 480

11.5.1 智能指針 480

11.5.2 演示unique_ptr 480

11.5.3 unique_ptr的所有權 482

11.5.4 指向內置數組的unique_ptr 482

11.6 MyArray案例學習:通過操作符重載來打造有價值的類 483

11.6.1 特殊成員函數 484

11.6.2 使用MyArray類 485

11.6.3 MyArray類定義 495

11.6.4 指定了MyArray大小的構造函數 496

11.6.5 C++11向構造函數傳遞一個大括號初始化器 497

11.6.6 拷貝構造函數和拷貝賦值操作符 498

11.6.7 移動構造函數和移動賦值操作符 502

11.6.8 析構函數 504

11.6.9 toString和size函數 505

11.6.10 重載相等性(==)和不相等(!=)操作符 506

11.6.11 重載下標([])操作符 508

11.6.12 重載一元bool轉換操作符 509

11.6.13 重載前遞增操作符 509

11.6.14 重載後遞增操作符 510

11.6.15 重載加賦值操作符(+=) 511

11.6.16 重載二元流提取(>>)和流插入(<<)操作符 512

11.6.17 友元函數swap 514

11.7 C++20三路比較操作符(<=>) 515

11.8 類型之間的轉換 518

11.9 explicit構造函數和轉換操作符 519

11.10 重載函數調用操作符() 522

11.11 小結 522

第12章 異常和對契約的展望

12.1 導讀 528

12.2 異常處理控制流 531

12.2.1 定義一個異常類來表示可能發生的問題類型 531

12.2.2 演示異常處理 532

12.2.3 將代碼封閉到try塊中 533

12.2.4 為DivideByZeroException定義catch處理程序 534

12.2.5 異常處理的終止模型 535

12.2.6 用戶輸入非零分母時的控制流 535

12.2.7 用戶輸入零分母時的控制流 535

12.3 異常安全保證和noexcept 536

12.4 重新拋出異常 537

12.5 棧展開和未捕捉的異常 539

12.6 什麽時候使用異常處理 541

12.6.1 assert宏 542

12.6.2 快速失敗 543

12.7 構造函數、析構函數和異常處理 543

12.7.1 從構造函數拋出異常 543

12.7.2 通過函數try塊在構造函數中捕獲異常 544

12.7.3 異常和析構函數:再論noexcept(false) 546

12.8 處理new的失敗 547

12.8.1 new在失敗時拋出bad_alloc 548

12.8.2 new在失敗時返回nullptr 549

12.8.3 使用set_new_handler函數處理new的失敗 549

12.9 標準庫異常層次結構 551

12.10 C++的finally塊替代方案:資源獲取即初始化(RAII) 553

12.11 一些庫同時支持異常和錯誤碼 554

12.12 日誌記錄 555

12.13 展望“契約” 555

12.14 小結 563

第Ⅳ部分 標準庫容器、迭代器和算法

第13章 標準庫容器和迭代器

13.1 導讀 572

13.2 容器簡介 574

13.2.1 序列和關聯式容器中的通用嵌套類型 575

13.2.2 通用容器成員和非成員函數 576

13.2.3 對容器元素的要求 578

13.3 使用迭代器 579

13.3.1 使用istream_iterator進行輸入,使用ostream_iterator進行輸出 579

13.3.2 迭代器的類別 580

13.3.3 容器對迭代器的支持 581

13.3.4 預定義迭代器類型名稱 582

13.3.5 迭代器操作符 582

13.4 算法簡介 583

13.5 序列容器 584

13.6 vector序列容器 584

13.6.1 使用vector和迭代器 585

13.6.2 vector元素處理函數 589

13.7 list順序容器 593

13.8 deque序列容器 598

13.9 關聯式容器 600

13.9.1 multiset關聯式容器 600

13.9.2 set關聯式容器 605

13.9.3 multimap關聯式容器 607

13.9.4 map關聯式容器 609

13.10 容器適配器 611

13.10.1 stack適配器 611

13.10.2 queue適配器 613

13.10.3 priority_queue適配器 614

13.11 bitset近似容器 616

13.12 選讀:Big O簡介 618

13.13 選讀:哈希表簡介 621

13.14 小結 622

第14章 標準庫算法和C++20範圍/視圖

14.1 導讀 626

14.2 算法要求:C++20“概念” 627

14.3 lambda和算法 629

14.4 算法 633

14.4.1 fill、fill_n、generate和generate_n 633

14.4.2 equal、mismatch和lexicographical_compare 636

14.4.3 remove、remove_if、remove_copy和remove_copy_if 639

14.4.4 replace、replace_if、replace_copy和replace_copy_if 643

14.4.5 打散、計數和最小/最大元素算法 645

14.4.6 查找和排序算法 649

14.4.7 swap、iter_swap和swap_ranges 654

14.4.8 copy_backward、merge、unique、reverse、copy_if和copy_n 656

14.4.9 inplace_merge、unique_copy和reverse_copy 660

14.4.10 集合操作 662

14.4.11 lower_bound、upper_bound和equal_range 665

14.4.12 min、max和minmax 667

14.4.13 來自頭文件<numeric>的算法gcd、lcm、iota、reduce和partial_sum 669

14.4.14 堆排序和優先隊列 672

14.5 函數對象(仿函數) 677

14.6 投射 682

14.7 C++20視圖和函數式編程 685

14.7.1 範圍適配器 685

14.7.2 使用範圍適配器和視圖 686

14.8 並行算法簡介 691

14.9 標準庫算法小結 693

14.10 C++23“範圍”前瞻 696

14.11 小結 696

第Ⅴ部分 高級編程主題

第15 章 模板、C++20“概念”和元編程 703

15.1 導讀 704

15.2 自定義類模板和編譯時多態性 707

15.3 C++20對函數模板的增強 712

15.3.1 C++20縮寫函數模板 712

15.3.2 C++20模板化lambda 714

15.4 C++20“概念”初探 714

15.4.1 無約束的函數模板multiply 715

15.4.2 帶有C++20“概念”的requires子句的有約束的函數模板 718

15.4.3 C++20預定義概念 721

15.5 類型traits 722

15.6 C++20概念:深入瞭解 728

15.6.1 創建自定義概念 728

15.6.2 使用概念 728

15.6.3 在縮寫函數模板中使用概念 729

15.6.4 基於概念的重載 731

15.6.5 requires表達式 733

15.6.6 C++20僅供參詳的概念 736

15.6.7 C++20“概念”之前的技術:SFINAE和Tag Dispatch 738

15.7 用static_assert測試C++20概念 738

15.8 創建自定義算法 741

15.9 創建自定義容器和迭代器 743

15.9.1 類模板ConstIterator 745

15.9.2 類模板Iterator 748

15.9.3 類模板MyArray 751

15.9.4 針對大括號初始化的MyArray推導指引 754

15.9.5 將MyArray及其自定義迭代器用於std::ranges算法 756

15.10 模板類型參數的默認實參 760

15.11 變量模板 761

15.12 可變參數模板和折疊表達式 761

15.12.1 tuple可變參數類模板 761

15.12.2 可變參數函數模板和C++17折疊表達式簡介 765

15.12.3 折疊表達式的類型 769

15.12.4 一元折疊表達式如何應用它們的操作符 769

15.12.5 二元折疊表達式如何應用它們的操作符 772

15.12.6 使用逗號操作符重復執行一個操作 774

15.12.7 將參數包中的元素約束為同一類型 774

15.13 模板元編程 777

15.13.1 C++模板是圖靈完備的 778

15.13.2 在編譯時計算值 778

15.13.3 用模板元編程和constexpr if進行條件編譯 783

15.13.4 類型元函數 785

15.14 小結 789

第16章 C++20模塊:大規模開發

16.1 導讀 798

16.2 C++20之前的編譯和鏈接 799

16.3 模塊的優點與目標 800

16.4 示例:過渡到模塊——頭單元 801

16.5 模塊可以減少翻譯單元的大小和編譯時間 804

16.6 示例:創建並使用模塊 805

16.6.1 模塊接口單元的module聲明 806

16.6.2 導出聲明 808

16.6.3 導出一組聲明 808

16.6.4 導出命名空間 808

16.6.5 導出命名空間的成員 809

16.6.6 導入模塊以使用其導出的聲明 809

16.6.7 示例:試圖訪問未導出的模塊內容 811

16.7 全局模塊片斷 814

16.8 將接口與實現分開 814

16.8.1 示例:模塊實現單元 815

16.8.2 示例:模塊化一個類 818

16.8.3 :private模塊片斷 821

16.9 分區 822

16.9.1 示例:模塊接口分區單元 822

16.9.2 模塊實現分區單元 825

16.9.3 示例:“子模塊”和分區 825

16.10 其他模塊示例 830

16.10.1 示例:將C++標準庫作為模塊導入 831

16.10.2 示例:不允許循環依賴 832

16.10.3 示例:導入不具傳遞性 833

16.10.4 示例:可見性和可達性 834

16.11 將代碼遷移到模塊 836

16.12 模塊和模塊工具的未來 837

16.13 小結 838

第17章 並行算法和並發性:高級觀點

17.1 導讀 852

17.2 標準庫並行算法(C++17) 855

17.2.1 示例:分析順序排序和並行排序算法 855

17.2.2 什麽時候使用並行算法 858

17.2.3 執行策略 859

17.2.4 示例:分析並行化和矢量化運算 859

17.2.5 並行算法的其他註意事項 862

17.3 多線程編程 863

17.3.1 線程狀態和線程生命周期 863

17.3.2 死鎖和無限期推遲 865

17.4 用std::jthread啟動線程 867

17.4.1 定義在線程中執行的任務 868

17.4.2 在一個jthread中執行任務 869

17.4.3 jthread對thread的修正 872

17.5 生產者-消費者關系:首次嘗試 873

17.6 生產者-消費者:同步對共享可變數據的訪問 881

17.6.1 SynchronizedBuffer類:互斥體、鎖和條件變量 882

17.6.2 測試SynchronizedBuffer 889

17.7 生產者-消費者:用循環緩沖區最小化等待時間 894

17.8 讀者和寫者 904

17.9 協作式取消jthread 905

17.10 用std::async啟動任務 909

17.11 線程安全的一次性初始化 916

17.12 原子類型簡介 917

17.13 用C++20閉鎖和柵欄來協同線程 921

17.13.1 C++20 std::latch 921

17.13.2 C++20 std::barrier 924

17.14 C++20信號量 928

17.15 C++23:C++並發性未來展望 932

17.15.1 並行範圍算法 932

17.15.2 並發容器 932

17.15.3 其他和並發性相關的提案 933

17.16 小結 933

第18章 C++20協程

18.1 導讀 942

18.2 協程支持庫 943

18.3 安裝concurrencpp和generator庫 944

18.4 用co_yield和generator庫創建生成器協程 944

18.5 用concurrencpp啟動任務 948

18.6 用co_await和co_return創建協程 953

18.7 低級協程概念 962

18.8 C++23的協程改進計劃 964

18.9 小結 964

附錄A 操作符優先級和分組 969

附錄B 字符集