C++ Templates, 2/e (簡體中文版)

[美] 戴維·範德沃德(David Vandevoorde) [德] 尼古拉 M. 約祖蒂斯(Nicolai M. Josuttis) [美] 道格拉斯·格雷戈(Douglas Gregor)

  • C++ Templates, 2/e (簡體中文版)-preview-1
  • C++ Templates, 2/e (簡體中文版)-preview-2
C++ Templates, 2/e (簡體中文版)-preview-1

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

商品描述

本書是一本全面介紹C++模板技術的圖書,主要內容涵蓋C++模板的基礎概念、語言細節、編程技巧、高級應用以及實用示例等。本書針對C++11、C++14、C++17標準進行了內容更新,並對很多新語言特性(包括變量模板、泛型lambda、類模板參數推導等)給出詳細解釋。通過閱讀本書,讀者可以深入理解C++模板技術,掌握開發有效、簡潔且易維護的軟件的原因、時機和方法。

本書內容豐富,架構清晰,講解翔實,適合對C++模板技術感興趣的開發人員或愛好者閱讀。

作者簡介

David Vandevoorde是Edison Design Group公司的工程副总裁,负责设计公司C++编译器的关键功能。他是comp.lang.c++.moderated论坛的创办人之一,也是C++标准化的积极参与者。他拥有伦斯勒理工学院的计算机科学博士学位和硕士学位,以及布鲁塞尔自由大学的工程硕士学位。他的技术兴趣包括算法开发和培训。

 

Nicolai M. Josuttis是一名独立的系统架构师、技术经理、顾问和培训师,20多年来一直活跃在C++标准化领域。作为库工作组的成员,他特别关注普通开发人员的观点。他是《C++标准库(第2版)》等图书的作者。

 

Douglas Gregor是一名经验丰富的编译器开发人员,具有C++库设计背景。作为Boost的早期贡献者,他开发的多个库已成为C++标准的一部分。后来,他作为代码所有者负责开源Clang C++编译器的实施,直至完成对C++11的支持,并积极参与了C++11的标准化工作。他拥有伦斯勒理工学院的计算机科学博士学位。

目錄大綱

第 一部分 基礎知識

第 1章 函數模板 2

1.1 函數模板初探 2

1.1.1 定義模板 2

1.1.2 使用模板 3

1.1.3 兩階段編譯 4

1.2 模板實參推導簡介 5

1.3 多模板參數 7

1.3.1 返回類型的模板參數 7

1.3.2 推導返回類型 8

1.3.3 返回類型為公共類型 9

1.4 默認模板實參簡介 10

1.5 重載函數模板簡介 11

1.6 難道,我們不應該…… 16

1.6.1 傳值還是傳引用 16

1.6.2 為什麽不使用inline 16

1.6.3 為什麽不使用constexpr 16

1.7 小結 17

第 2章 類模板 18

2.1 類模板Stack的實現 18

2.1.1 類模板的聲明 19

2.1.2 成員函數的實現 20

2.2 類模板Stack的使用 21

2.3 部分使用類模板 22

2.4 友元簡介 24

2.5 類模板的特化 25

2.6 偏特化 26

2.7 默認類模板實參 28

2.8 類型別名 30

2.9 類模板實參推導 32

2.10 模板化聚合體 35

2.11 小結 35

第3章 非類型模板參數 36

3.1 非類型的類模板參數 36

3.2 非類型的函數模板參數 38

3.3 非類型模板參數的限制 39

3.4 模板參數類型auto 40

3.5 小結 43

第4章 變參模板 44

4.1 變參模板簡介 44

4.1.1 變參模板示例 44

4.1.2 變參和非變參模板的重載 45

4.1.3 sizeof...運算符 46

4.2 折疊表達式 46

4.3 變參模板應用 48

4.4 變參類模板和變參表達式 49

4.4.1 變參表達式 49

4.4.2 變參索引 50

4.4.3 變參類模板 51

4.4.4 變參推導指引 52

4.4.5 變參基類和using關鍵字 52

4.5 小結 54

第5章 基本技巧 55

5.1 關鍵字typename 55

5.2 零初始化 56

5.3 使用this-> 58

5.4 處理原始數組和字符串字面量的模板 58

5.5 成員模板 60

5.5.1 .template構造 65

5.5.2 泛型lambda和成員模板 65

5.6 變量模板 66

5.7 模板的模板參數簡介 68

5.8 小結 73

第6章 移動語義和enable_if<> 74

6.1 完美轉發簡介 74

6.2 特殊成員函數模板 77

6.3 通過std::enable_if<>禁用 模板 79

6.4 使用enable_if<> 81

6.5 使用概念簡化enable_if<> 表達式 84

6.6 小結 85

第7章 傳值還是傳引用 86

7.1 傳值 86

7.2 傳引用 88

7.2.1 傳遞常量引用 88

7.2.2 傳遞非常量引用 90

7.2.3 傳遞轉發引用 91

7.3 使用std::ref()和std::cref() 92

7.4 處理字符串字面量和原始 數組 94

7.5 處理返回值 95

7.6 推薦的模板參數聲明方法 97

7.7 小結 99

第8章 編譯期編程 100

8.1 模板元編程 100

8.2 使用constexpr計算 102

8.3 偏特化的執行路徑選擇 103

8.4 SFINAE 104

8.5 編譯期if簡介 108

8.6 小結 110

第9章 在實踐中使用模板 111

9.1 包含模型簡介 111

9.1.1 鏈接器錯誤 111

9.1.2 頭文件中的模板 112

9.2 模板和inline 113

9.3 預編譯頭文件 114

9.4 破譯大篇錯誤信息 115

9.5 後記 122

9.6 小結 122

第 10章 模板基本術語 123

10.1 是“類模板”還是 “模板類” 123

10.2 替換、實例化和特化 123

10.3 聲明和定義 124

10.4 單一定義規則 126

10.5 模板實參和模板形參 126

10.6 小結 127

第 11章 泛型庫 128

11.1 可調用對象 128

11.1.1 函數對象的支持 128

11.1.2 處理成員函數及額外的 參數 130

11.1.3 封裝函數調用 132

11.2 實現泛型庫的其他工具 133

11.2.1 類型特徵 133

11.2.2 std::addressof() 135

11.2.3 std::declval() 135

11.3 完美轉發臨時變量 136

11.4 作為模板參數的引用 137

11.5 推遲估算 140

11.6 關於泛型庫的思考 141

11.7 小結 141

第二部分 深入模板

第 12章 深入模板基礎 144

12.1 參數化的聲明 144

12.1.1 虛成員函數 148

12.1.2 模板的鏈接 148

12.1.3 主模板 150

12.2 模板參數 150

12.2.1 類型參數 150

12.2.2 非類型參數 151

12.2.3 模板的模板參數 152

12.2.4 模板參數包 153

12.2.5 默認模板實參 154

12.3 模板實參 156

12.3.1 函數模板實參 156

12.3.2 類型實參 158

12.3.3 非類型模板實參 158

12.3.4 模板的模板實參 160

12.3.5 實參的等價性 162

12.4 變參模板 163

12.4.1 包擴展 163

12.4.2 包擴展的時機 164

12.4.3 函數參數包 166

12.4.4 多重和嵌套包擴展 167

12.4.5 零長度包擴展 168

12.4.6 折疊表達式 169

12.5 友元 170

12.5.1 類模板的友元類 170

12.5.2 類模板的友元函數 171

12.5.3 友元模板 173

12.6 後記 174

第 13章 模板中的名稱 175

13.1 名稱的分類 175

13.2 名稱查找 177

13.2.1 依賴於參數的查找 178

13.2.2 依賴於參數的友元 聲明的查找 179

13.2.3 註入的類名稱 180

13.2.4 當前的實例化 181

13.3 解析模板 183

13.3.1 非模板中的上下文 相關性 183

13.3.2 依賴類型的名稱 186

13.3.3 依賴模板的名稱 188

13.3.4 using聲明中的依賴型 名稱 189

13.3.5 ADL和顯式模板實參 190

13.3.6 依賴型表達式 190

13.3.7 編譯器錯誤 192

13.4 繼承和類模板 193

13.4.1 非依賴型基類 193

13.4.2 依賴型基類 194

13.5 後記 196

第 14章 實例化 198

14.1 按需實例化 198

14.2 延遲實例化 200

14.2.1 部分和完全實例化 200

14.2.2 實例化組件 200

14.3 C++的實例化模型 203

14.3.1 兩階段查找 203

14.3.2 實例化點 204

14.3.3 包含模型 207

14.4 實現方案 207

14.4.1 貪婪實例化 209

14.4.2 查詢實例化 210

14.4.3 迭代實例化 211

14.5 顯式實例化 212

14.5.1 手動實例化 212

14.5.2 顯式實例化聲明 214

14.6 編譯期的if語句 215

14.7 標準庫 216

14.8 後記 217

第 15章 模板實參推導 218

15.1 推導的過程 218

15.2 推導的上下文 220

15.3 特殊的推導情況 221

15.4 初始化列表 222

15.5 參數包 223

15.6 右值引用 225

15.6.1 引用折疊規則 225

15.6.2 轉發引用 226

15.6.3 完美轉發 227

15.6.4 推導的意外情況 229

15.7 SFINAE 230

15.8 推導的限制 233

15.8.1 可行的實參轉換 233

15.8.2 類模板實參 234

15.8.3 默認調用實參 234

15.8.4 異常規範 235

15.9 顯式函數模板參數 236

15.10 基於初始化器和表達式的 推導 238

15.10.1 auto類型的規範 238

15.10.2 使用decltype表示一個表達式的類型 242

15.10.3 decltype(auto) 244

15.10.4 auto推導的特殊 情況 246

15.10.5 結構化綁定 249

15.10.6 泛型lambda表達式 252

15.11 別名模板 254

15.12 類模板參數推導 255

15.12.1 推導指引 256

15.12.2 隱式推導指引 257

15.12.3 其他 259

15.13 後記 262

第 16章 特化與重載 264

16.1 當“泛型代碼”不是特別適用的時候 264

16.1.1 透明自定義 265

16.1.2 語義的透明性 266

16.2 重載函數模板 267

16.2.1 簽名 267

16.2.2 重載的函數模板的局部排序 269

16.2.3 正式的排序規則 270

16.2.4 模板和非模板 272

16.2.5 變參函數模板 274

16.3 顯式特化 276

16.3.1 全局的類模板特化 276

16.3.2 全局的函數模板特化 279

16.3.3 全局的變量模板特化 281

16.3.4 全局的成員特化 281

16.4 類模板偏特化 284

16.5 變量模板偏特化 287

16.6 後記 287

第 17章 未來方向 289

17.1 寬松的typename規則 289

17.2 廣義非類型模板參數 290

17.3 函數模板的偏特化 292

17.4 命名模板實參簡介 293

17.5 重載類模板 294

17.6 中間包擴展的演繹 294

17.7 void的規則化 295

17.8 模板的類型檢查 296

17.9 反射元編程 297

17.10 包管理工具 298

17.11 模塊 299

第三部分 模板與設計

第 18章 模板的多態 302

18.1 動多態 302

18.2 靜多態 304

18.3 動多態與靜多態 306

18.4 使用概念 308

18.5 新形式的設計模式 309

18.6 泛型程序設計 310

18.7 後記 312

第 19章 特徵的實現 314

19.1 一個實例:累加一個序列 314

19.1.1 固定特徵 314

19.1.2 值特徵 317

19.1.3 參數化特徵 321

19.2 特徵、policy及policy類 321

19.2.1 特徵和policy的區別 323

19.2.2 成員模板和模板的模板 參數 324

19.2.3 組合多個policy和(或)特徵 325

19.2.4 運用普通的迭代器進行累積 325

19.3 類型函數 326

19.3.1 元素類型 327

19.3.2 轉換特徵 329

19.3.3 謂詞特徵 334

19.3.4 結果類型特徵 336

19.4 基於SFINAE的特徵 339

19.4.1 SFINAE函數重載 339

19.4.2 SFINAE偏特化 342

19.4.3 為SFINAE使用泛型lambda表達式 343

19.4.4 SFINAE友好的特徵 346

19.5 IsConvertibleT 349

19.6 檢測成員 351

19.6.1 檢測成員類型 351

19.6.2 檢測任意的成員類型 353

19.6.3 檢測nontype成員 354

19.6.4 使用泛型lambda檢測 成員 357

19.7 其他特徵技術 359

19.7.1 if-then-else 359

19.7.2 檢測nonthrowing 操作 362

19.7.3 特徵的便利性 364

19.8 類型分類 366

19.8.1 確定基本類型 366

19.8.2 確定復合類型 368

19.8.3 識別函數類型 371

19.8.4 確定類類型 372

19.8.5 確定枚舉類型 373

19.9 policy特徵 373

19.10 在標準庫中 376

19.11 後記 377

第 20章 類型屬性重載 379

20.1 算法特化 379

20.2 標簽調度 380

20.3 啟用/禁用函數模板 382

20.3.1 提供多種特化 383

20.3.2 EnableIf去往何處 385

20.3.3 編譯期if 386

20.3.4 術語 387

20.4 類特化 388

20.4.1 啟用/禁用類模板 388

20.4.2 類模板的標簽調度 390

20.5 實例化安全模板 392

20.6 在標準庫中 396

20.7 後記 396

第 21章 模板與繼承 398

21.1 空基類優化 398

21.1.1 佈局原則 398

21.1.2 作為基類的成員 400

21.2 奇妙遞歸模板模式 402

21.2.1 Barton-Nackman 技巧 404

21.2.2 運算符實現 406

21.2.3 門面模式 407

21.3 混入 413

21.3.1 奇妙的混入 415

21.3.2 參數化的虛擬性 415

21.4 命名模板實參 416

21.5 後記 419

第 22章 橋接靜多態與動多態 421

22.1 函數對象、指針以及std::function<> 421

22.2 泛化的函數指針 423

22.3 橋接接口 425

22.4 類型擦除 426

22.5 可選的橋接 427

22.6 性能考慮 429

22.7 後記 429

第 23章 元編程 431

23.1 現代C++元編程的狀況 431

23.1.1 值元編程 431

23.1.2 類型元編程 432

23.1.3 混合元編程 433

23.1.4 單位類型的混合元編程 435

23.2 反射元編程的維度 437

23.3 遞歸實例化的代價 438

23.4 計算完備性 441

23.5 遞歸實例化還是遞歸模板實參 441

23.6 枚舉值還是靜態常量 442

23.7 後記 443

第 24章 類型列表 446

24.1 解剖一個類型列表 446

24.2 類型列表算法 448

24.2.1 索引 448

24.2.2 尋找最佳匹配 449

24.2.3 追加元素到類型 列表 451

24.2.4 反轉類型列表 453

24.2.5 轉化類型列表 454

24.2.6 累加類型列表 455

24.2.7 插入排序 457

24.3 非類型類型列表 459

24.4 使用包擴展來優化算法 462

24.5 cons風格的類型列表 463

24.6 後記 465

第 25章 元組 466

25.1 基礎元組設計 466

25.1.1 存儲 466

25.1.2 構造 468

25.2 基礎元組運算 469

25.2.1 比較 469

25.2.2 輸出 470

25.3 元組算法 471

25.3.1 作為類型列表 471

25.3.2 增刪 472

25.3.3 反轉 473

25.3.4 索引列表 474

25.3.5 用索引列表反轉 475

25.3.6 重排和選擇 477

25.4 展開元組 480

25.5 優化元組 480

25.5.1 元組和EBCO 481

25.5.2 常數時間復雜度的get() 484

25.6 元組索引 485

25.7 後記 487

第 26章 可辨識聯合體 489

26.1 存儲簡介 490

26.2 設計 491

26.3 值的查詢與提取 494

26.4 元素初始化、賦值和析構 495

26.4.1 初始化 495

26.4.2 析構 496

26.4.3 賦值 497

26.5 訪問者 500

26.5.1 訪問結果類型 503

26.5.2 公共結果類型 504

26.6 variant的初始化和賦值 505

26.7 後記 508

第 27章 表達式模板 510

27.1 臨時變量和割裂的循環 510

27.2 在模板實參中對表達式編碼 514

27.2.1 表達式模板的操作數 515

27.2.2 Array類型 518

27.2.3 運算符 520

27.2.4 回顧 521

27.2.5 表達式模板賦值 523

27.3 表達式模板的性能與局限 524

27.4 後記 524

第 28章 調試模板 527

28.1 淺層實例化 527

28.2 靜態斷言 529

28.3 原型 530

28.4 追蹤器 532

28.5 預言機 535

28.6 後記 536

附錄A 單一定義規則 537

A.1 編譯單元 537

A.2 聲明和定義 538

A.3 單一定義規則的細節 539

A.3.1 程序中的單一定義約束 539

A.3.2 編譯單元中的單一定義約束 540

A.3.3 跨編譯單元的等價性約束 542

附錄B 值類別 545

B.1 傳統的左值和右值 545

B.2 C++11值類別 546

B.3 使用decltype檢查值類別 549

B.4 引用類型 549

附錄C 重載解析 551

C.1 何時應用重載解析 551

C.2 簡化過的重載解析 552

C.2.1 成員函數的隱含實參 554

C.2.2 精細完美匹配 555

C.3 重載的細節 556

C.3.1 非模板優先或更特化的模板 557

C.3.2 轉換序列 557

C.3.3 指針的轉型 558

C.3.4 初始化列表 559

C.3.5 仿函數和代理函數 562

C.3.6 其他的重載情況 562

附錄D 標準庫類型實用程序 564

D.1 使用類型特徵 564

D.1.1 std::integral_constant和std::bool_constant 565

D.1.2 使用特徵時應該知道的事 566

D.2 基本和復合類型類別 567

D.2.1 基本類型類別的測試 567

D.2.2 復合類型類別的測試 571

D.3 類型屬性和操作 572

D.3.1 其他類型屬性 572

D.3.2 特定操作測試 580

D.3.3 類型之間的關系 587

D.4 類型構造 589

D.5 其他特徵 593

D.6 組合類型特徵 595

D.7 其他工具 596

附錄E 概念 598

E.1 使用概念 598

E.2 定義概念 600

E.3 約束的重載 602

E.3.1 約束的歸並 602

E.3.2 約束和標簽調度 603

E.4 概念小提示 604

E.4.1 測試概念 604

E.4.2 概念粒度 604

E.4.3 二進制兼容性 605

術語表 607