學(xué)習(xí)元編程技術(shù)如何創(chuàng)建數(shù)據(jù)結(jié)構(gòu)和函數(shù),從而在編譯時進(jìn)行計算。通過《C 20模板元編程》,你將理解模板如何幫助你避免編寫重復(fù)代碼,模板是創(chuàng)建通用庫(如標(biāo)準(zhǔn)庫或Boost)的關(guān)鍵,這些庫可以在多種程序中使用。
本書的前幾章將為你提供關(guān)于模板和元編程基礎(chǔ)的知識。然后,你將開始練習(xí)編寫復(fù)雜的模板,并探索高級概念,如模板遞歸、模板實參推導(dǎo)、轉(zhuǎn)發(fā)引用、類型特征和條件編譯。在此過程中,你將學(xué)習(xí)如何編寫變參模板,以及如何使用C 20的約束和概念為模板實參提供約束和限制。最后,你將應(yīng)用C 元編程模板的知識實現(xiàn)各種元編程模式和技術(shù)。
到本書結(jié)束時,你將學(xué)會如何編寫有效的模板,并在日常編程中使用元編程。
● 理解所有類型模板的語法
● 學(xué)習(xí)特化和實例化的工作原理
● 掌握模板實參推導(dǎo)和轉(zhuǎn)發(fā)引用
● 輕松編寫變參模板
● 掌握類型特征和條件編譯
● 使用 C 20 的約束和概念限制模板實參
● 實現(xiàn)CRTP、混入(mixin)和標(biāo)簽派發(fā)等模式
玄之又玄,眾妙之門
大家都知道,AI可以寫代碼了。你用過嗎?感覺如何?
前不久,我在準(zhǔn)備GPU訓(xùn)練營的試驗程序時,確實用AI寫了一些代碼,既有傳統(tǒng)的CPU端代碼,也有更現(xiàn)代的GPU端代碼。我用AI寫代碼的目的有兩個,一是提高工作效率,二是親身測試AI寫代碼的能力。
親身測試一番之后,我有兩個比較強(qiáng)烈的感受。第一個感受是對于比較簡單的任務(wù),AI確實可以寫出質(zhì)量不錯的代碼,不僅速度快,而且準(zhǔn)確度很高,沒有誤拼等人類常犯的低級錯誤。第二個感受是,隨著代碼量的上升,AI寫的代碼也開始具有人類代碼常有的問題,先是重復(fù),啰嗦,然后是有bug(錯誤)。
眾所周知,AI領(lǐng)域吸引了大量的投資和優(yōu)秀的人才,新的成果不斷涌現(xiàn)。因此,我們比較難預(yù)測AI的代碼能力在2年后會怎么樣?在5年和10年后又會怎么樣?
AI技術(shù)的發(fā)展速度難以預(yù)測,但是我覺得以下三個趨勢是比較確定的。首先,AI技術(shù)確實會改變軟件產(chǎn)業(yè)的格局,一些簡單的軟件開發(fā)任務(wù)將AI化,因為使用AI技術(shù)能大大提高編碼的效率,不再需要那么多的程序員來寫代碼。第二,隨著AI技術(shù)不斷被應(yīng)用到軟件開發(fā)領(lǐng)域,軟件的產(chǎn)量和軟件的代碼量都將隨之上升。而且,AI產(chǎn)生的代碼也是不完美并且存在瑕疵的。軟件團(tuán)隊里將需要很多調(diào)試工程師來定位各種稀奇古怪的問題。第三,在追求高性能、高可靠性的某些領(lǐng)域里,仍需要優(yōu)秀的人類程序員來編寫極端精致的代碼。就像在機(jī)器可以包餃子的今天,仍有某些餃子店使用人工包。
其實,不管我的預(yù)測是否對,一名好的程序員都應(yīng)該不斷錘煉自己的編碼能力,提高技術(shù)水平,讓自己寫出的代碼越來越好。
于是,可能有人問,我已經(jīng)能寫出很漂亮的代碼,什么樣的代碼算是更好呢?
的確,評價代碼好壞的標(biāo)準(zhǔn)有很多。在我看來,第一個硬指標(biāo)就是generic,也就是通用性。展開來說,很多代碼都有的一個通病就是長相類似的代碼有很多份,結(jié)構(gòu)類似,但有差異,不完全相同。
我是信儒家的,但偶爾也會讀一點道家的作品,一般是在睡前讀,因為讀道家的作品讀著讀著就昏昏欲睡了。為什么呢?因為道家的話一般都比較虛空。用時髦的話說,就是不接地氣,難以琢磨。比如一句道可道,非常道就有很多種解釋。
我對道家的這種態(tài)度持續(xù)了很多年,直到有一天,當(dāng)我領(lǐng)悟了計算機(jī)世界的一系列經(jīng)典案例和一個永恒規(guī)律后,我又看到了玄之又玄,眾妙之門。這八個字歸納得太好了,說出我心中所有,筆下所無,改變了我對道家的態(tài)度。
什么是玄而又玄呢?傳統(tǒng)的解釋有很多種,對多數(shù)程序員來說,都不大好理解。
在我看來,玄就是抽象。玄之又玄,就是抽象了再抽象。
人類的大腦喜歡生動具體的東西,比如小孩子都喜歡聽故事,無論是小馬過河還是后羿射日都有具體的場景、人和物。長大了以后喜歡刷劇也是類似的原因。每部劇都在一個具體的時空中講一個故事。沒有哪部劇沒有人物,只有道可道,非常道。
因此,做抽象是很難的事情。也因此,很多代碼都是不夠抽象的,今天需要int類型的max()函數(shù),那么就寫個int類型的;明天需要float類型的,就把int類型的復(fù)制一份,改成float類型的。日積月累,整個項目里就有很多長相類似的代碼了。
如何提煉這樣的代碼,消除重復(fù),把它們合眾為一呢?
傳統(tǒng)C 中的模板技術(shù)就是為解決這個問題而設(shè)計的,現(xiàn)代C 將其發(fā)揚(yáng)光大, 去除約束,增加功能,使其成為現(xiàn)代C 語言的一大亮點。
我認(rèn)識文波和榮華多年,他們都在C 語言和編程技術(shù)領(lǐng)域耕耘多年,孜孜不倦,滿懷深情。更加可貴的是,他們把熱愛轉(zhuǎn)化為實際的行動,以各種形式推動技術(shù)的傳播和發(fā)展。他們在翻譯《C 模板》(第2版)之后,又將另一本模板編程的好書《C 20模板元編程》翻譯成中文,功莫大焉。
張銀奎
《軟件調(diào)試》和《軟件簡史》的作者
譯 者 序
C 的演化與模板的歷史
自1979年Bjarne Stroustrup 創(chuàng)建C 以來,這門語言經(jīng)歷了多個重要的標(biāo)準(zhǔn)化版本,每一次演進(jìn)都帶來了新的特性和改進(jìn)。從C 98的標(biāo)準(zhǔn)化到C 11迎來現(xiàn)代C 編程范式,再到C 14、C 17的穩(wěn)定和擴(kuò)展,現(xiàn)在C 20作為一個里程碑式的更新,引入了概念(Concepts)、范圍(Ranges)、協(xié)程(Coroutines)等強(qiáng)大特性。其中,C 20對模板系統(tǒng)的擴(kuò)展和改進(jìn),使得泛型編程更加直觀、高效。
C 模板的歷史可以追溯到20世紀(jì)80年代后期,它最初是為了解決代碼復(fù)用的問題。1998年的C 標(biāo)準(zhǔn)(C 98)正式引入了模板,隨后在C 11中得到了重要增強(qiáng),如變參模板(Variadic Templates)、模板別名(Template Aliases)等。C 17進(jìn)一步引入了折疊表達(dá)式(Fold Expressions)和類模板實參推導(dǎo)(Class Template Argument Deduction,CTAD)。到了C 20,概念(Concepts)的加入使得模板的可讀性、可維護(hù)性大幅提升。
C 模板的優(yōu)勢
C 是一門支持多種編程范式的語言,包括:
●過程式編程(Procedural Programming)基于函數(shù)和過程的結(jié)構(gòu)化編程。
●面向?qū)ο缶幊?OOP)通過類、繼承和多態(tài)實現(xiàn)模塊化與復(fù)用。
●泛型編程(Generic Programming)借助模板編寫類型無關(guān)的代碼,提高代碼復(fù)用性和靈活性。
●函數(shù)式編程(Functional Programming)使用不可變數(shù)據(jù)和高階函數(shù),提升代碼可測試性和并發(fā)能力。
●元編程(Metaprogramming)利用編譯期計算優(yōu)化程序,提高運(yùn)行效率。
在這些范式中,模板技術(shù)是C 的核心特性,它賦予C 強(qiáng)大的泛型編程能力,使代碼適用于多種數(shù)據(jù)類型,而不需要冗余編寫。例如,標(biāo)準(zhǔn)模板庫(STL)的容器(如 std::vector、std::map)和算法(如 std::sort、std::find)均依賴模板實現(xiàn)。
C 模板的主要優(yōu)勢包括:
●編譯時多態(tài)(Compile-time Polymorphism)相比運(yùn)行時多態(tài)(如繼承與虛函數(shù)),模板允許編譯期進(jìn)行類型推導(dǎo)和優(yōu)化,從而提高執(zhí)行效率。
●編譯時計算(Compile-time Computation)利用模板元編程(TMP),C 能在編譯期執(zhí)行計算,減少運(yùn)行時開銷。例如,std::integral_constant 和 std::conditional 可用于選擇編譯期代碼路徑。
●代碼復(fù)用模板減少了重復(fù)代碼,提高了通用性。例如,std::enable_if 可用于 SFINAE(替換失敗非錯誤),實現(xiàn)條件編譯。
模板的強(qiáng)大使其在現(xiàn)代C 開發(fā)中占據(jù)重要地位,特別是在高性能計算、游戲開發(fā)、底層系統(tǒng)編程等領(lǐng)域。掌握模板不僅能提升代碼質(zhì)量,還能幫助程序員深入理解C 語言的底層機(jī)制。
C 程序員的技能
對于希望深入掌握C 的開發(fā)者而言,理解模板是進(jìn)階C 編程的必經(jīng)之路。從泛型編程(Generic Programming)、模板元編程(Template Metaprogramming),到C 20 概念(Concepts),這些技術(shù)都在現(xiàn)代C 開發(fā)中占據(jù)了重要地位。
無論是編寫高效的庫函數(shù),還是優(yōu)化應(yīng)用程序的性能,模板都是必不可少的工具。例如,在高性能計算(HPC)、游戲開發(fā)、底層系統(tǒng)編程等領(lǐng)域,模板能夠提供無與倫比的靈活性和效率。掌握模板不僅能夠提高代碼質(zhì)量,還能幫助程序員更深入地理解C 語言的底層機(jī)制。
模板技術(shù)的學(xué)習(xí)建議
模板技術(shù)屬于編譯期編程,在學(xué)習(xí)過程中,建議結(jié)合反匯編,并善用Cpp Insights 等工具來觀察模板實例化和生成的代碼。
要系統(tǒng)學(xué)習(xí)模板技術(shù),僅靠一本書是不夠的。推薦閱讀以下書籍:
●《C Templates (第2版·中文版)》[C Templates: The Complete Guide, 2nd Edition, (美)David Vandevoorde、(德)Nicolai M. Josuttis、(美)Douglas Gregor著,何榮華、王文斌、張毅峰、楊文波譯,人民郵電出版社]經(jīng)典的C 模板書籍,全面介紹了模板技術(shù)。
●《編程原本》[Elements of ?Programming,(美)Alexnader Stepanov、(美) Paul McJones著,裘宗燕譯,人民郵電出版社]和亞歷山大的系列博文(https://www.stepanovpapers.com/)進(jìn)一步深入泛型編程。
●《C實戰(zhàn):核心技術(shù)與最佳實踐》(吳詠煒著,人民郵電出版社)現(xiàn)代C 最佳實踐。
此外,學(xué)習(xí)模板技術(shù)不能只依賴?yán)碚,還需要實踐。建議閱讀并改造以下模板庫:
1. fmt(std::format的實現(xiàn))不依賴領(lǐng)域知識,適合作為入門教材。
2. blaze高性能數(shù)學(xué)庫作者 Klaus Iglberger 是模板設(shè)計模式專家。
3. folly庫Andrei Alexandrescu 主導(dǎo),適合學(xué)習(xí)模板元編程。
4. cutlass C 模板庫Nvidia 出品,適用于深度學(xué)習(xí)優(yōu)化。
結(jié)語與感謝
C 模板的強(qiáng)大使得它成為現(xiàn)代C 開發(fā)的基石,而C 20的更新更是讓模板變得更易用、更強(qiáng)大。本書的目標(biāo)是幫助讀者全面理解C 20模板的核心概念,并掌握如何在實際開發(fā)中高效地應(yīng)用模板技術(shù)。希望本書能為你打開C 模板編程的大門,幫助你在C 領(lǐng)域更進(jìn)一步。
本書的出版離不開各方的支持。我們衷心感謝 Bjarne Stroustrup教授,他的貢獻(xiàn)不僅塑造了C 語言,也為全球開發(fā)者提供了深遠(yuǎn)的技術(shù)指導(dǎo)。
特別感謝清華大學(xué)出版社的編輯團(tuán)隊,他們在術(shù)語規(guī)范、技術(shù)表達(dá)及出版質(zhì)量方面提供了寶貴的支持,付出了大量的辛勤工作,確保本書得以高質(zhì)量呈現(xiàn)。我們也感謝C 社區(qū)的開發(fā)者們,你們的深入討論與實踐經(jīng)驗為我們提供了極大的啟發(fā)。
盡管我們力求精確,但面對C 如此龐大而復(fù)雜的體系,難免仍有不足之處。我們誠懇歡迎讀者通過出版社反饋意見,以便我們進(jìn)一步完善后續(xù)的修訂工作。希望本書能夠幫助廣大開發(fā)者更深入地理解C ,更高效地運(yùn)用這門強(qiáng)大語言。
獻(xiàn)給那些總是渴望學(xué)習(xí)更多的好奇心靈。
Marius Bancila
貢 獻(xiàn) 者
關(guān)于作者
Marius Bancila 是一位擁有20年經(jīng)驗的軟件工程師,在業(yè)務(wù)應(yīng)用程序開發(fā)和其他領(lǐng)域都有豐富的解決方案經(jīng)驗。他是Modern C Programming Cookbook和The Modern C Challenge的作者。他目前擔(dān)任軟件架構(gòu)師,專注于微軟技術(shù),主要使用C 和C#開發(fā)桌面應(yīng)用程序。他熱衷于與他人分享技術(shù)專長,因此自2006年起一直被認(rèn)定為微軟C MVP,后來還獲得了開發(fā)者技術(shù)領(lǐng)域的 MVP 稱號。Marius 居住在羅馬尼亞,活躍于各種在線社區(qū)。
關(guān)于審校者
Aleksei Goriachikh擁有超過8年的C 編程經(jīng)驗。2012年從俄羅斯的新西伯利亞國立大學(xué)獲得數(shù)學(xué)碩士學(xué)位后,Aleksei曾參與一些計算數(shù)學(xué)和優(yōu)化領(lǐng)域的研究項目、某CAD系統(tǒng)的幾何內(nèi)核開發(fā),以及自動駕駛的多線程庫開發(fā)。Aleksei 最近的專業(yè)興趣是硅前建模。
前 言
幾十年來,C 一直是世界上使用最廣泛的編程語言之一。它的成功不僅僅歸功于其提供的性能或者說它的易用性(許多人對此持不同意見),而更可能是由于它的多功能性。C 是一種通用的多范式編程語言,它融合了過程式、函數(shù)式和泛型編程。
泛型編程是一種編寫代碼的方式,例如函數(shù)和類等實體是按照稍后實例化的類型編寫的。這些泛型實體僅在需要作為實參具化為特定類型時才會實例化,這些泛型實體在C 中稱為模板。
元編程是一種編程技術(shù),它使用模板(以及C 中的constexpr函數(shù))在編譯期生成代碼,然后將其與剩余源代碼合并以便編譯最終程序。元編程意味著其輸入或輸出中至少有一個是類型。
正如《C 核心指南》(Bjarne Stroustrup和Herb Sutter維護(hù)的一份關(guān)于應(yīng)該做什么和不應(yīng)該做什么的文檔)中所描述的那樣,C 中的模板可謂聲名狼藉。然而,它們使得泛型庫成為可能,比如C 開發(fā)人員一直使用的C 標(biāo)準(zhǔn)庫。無論你是自己編寫模板,還是只使用他人編寫的模板(比如標(biāo)準(zhǔn)容器或算法),模板都很可能是你日常編碼的一部分。
本書旨在讓讀者對C 中可用的所有范圍內(nèi)的模板都有很好的理解(從基本語法到C 20中的概念),這是本書前兩部分的重點內(nèi)容。第Ⅲ部分會幫助你將新獲得的知識付諸實踐,并使用模板進(jìn)行元編程。
本書適讀人群
本書適合想要學(xué)習(xí)模板元編程的初學(xué)者、中級C 開發(fā)人員,以及希望快速掌握與模板相關(guān)的C 20新功能和各種慣用法和模式的高級C 開發(fā)人員。在開始閱讀本書之前,必須具備基本的C 編程經(jīng)驗。
本書涵蓋內(nèi)容
第1章模板簡介。通過幾個簡單的例子介紹了C 中模板元編程的概念,討論了為什么我們需要模板以及模板的優(yōu)缺點。
第2章模板基礎(chǔ)。探討了C 中所有形式的模板:函數(shù)模板、類模板、變量模板和別名模板。我們討論了其中每一個的語法和它們?nèi)绾喂ぷ鞯募?xì)節(jié)。此外,還討論了模板實例化和特化的關(guān)鍵概念。
第3章變參模板。專門介紹了變參模板,即具有可變數(shù)量模板形參的模板。我們詳細(xì)討論了變參函數(shù)模板、變參類模板、變參別名模板和變參變量模板、形參包及其展開方式,以及幫助我們簡化編寫變參模板的折疊表達(dá)式。
第4章高級模板概念。對一系列高級模板概念進(jìn)行了分組,比如依賴名稱和名稱查找、模板實參推導(dǎo)、模板遞歸、完美轉(zhuǎn)發(fā)、泛型和模板lambda函數(shù)。通過了解這些主題,讀者將能夠極大地擴(kuò)展他們可以閱讀或編寫的模板的種類。
第5章類型特征和條件編譯。專門討論類型特征。讀者將了解類型特征、標(biāo)準(zhǔn)庫提供的特征以及如何使用它們解決不同的問題。
第6章概念和約束。介紹了新的C 20機(jī)制,通過概念和約束定義模板實參的需求。你將了解指定約束的各種方法。此外,還概述了C 20標(biāo)準(zhǔn)概念庫的內(nèi)容。
第7章模式和慣用法。探討了一系列獨(dú)立的高級主題,即利用迄今為止學(xué)到的知識實現(xiàn)各種模式。我們探討了靜態(tài)多態(tài)、類型擦除、標(biāo)簽派發(fā)和模式的概念,比如奇異遞歸模板模式、表達(dá)式模板、混入和類型列表。
第8章范圍和算法。專注于理解容器、迭代器和算法,它們是標(biāo)準(zhǔn)模板庫的核心組件。你將在這里學(xué)習(xí)如何為其編寫泛型容器和迭代器類型以及通用算法。
第9章范圍庫。探討了新的C 20范圍庫及其關(guān)鍵特性,例如范圍、范圍適配器和約束算法。這些使我們能夠編寫更簡單的代碼來處理范圍。此外,你還將在這里學(xué)習(xí)如何編寫自己的范圍適配器。
附錄是一個簡短的結(jié)語,提供了本書的總結(jié)。
問題答案包含了所有章節(jié)中習(xí)題的答案。
充分利用本書
要開始閱讀本書,首先需要對C 編程語言有一些基本的了解。需要了解有關(guān)類、函數(shù)、運(yùn)算符、函數(shù)重載、繼承、虛函數(shù)等的語法和基礎(chǔ)知識。不過,對模板知識不做要求,因為本書將從頭開始教你一切。
本書中的所有代碼示例都是跨平臺的。這意味著你可以使用任何編譯器來構(gòu)建和運(yùn)行它們。然而,盡管許多代碼段適用于C 11編譯器,但也有一些代碼段需要兼容C 17或C 20的編譯器。因此,建議你使用支持C 20的編譯器版本,以便運(yùn)行所有示例。書中的示例已使用MSVC 19.30 (Visual Studio 2022)、GCC 12.1/13和Clang 13/14進(jìn)行了測試。如果你的機(jī)器上沒有這樣一個兼容C 20的編譯器,可以試著網(wǎng)上下載一個。我們推薦以下幾個方案:
●Compiler Explorer (https://godbolt.org/)
●Wandbox (https://wandbox.org/)
●C Insights (https://cppinsights.io/)
本書多次引用C Insights在線工具來分析編譯器生成的代碼。
如果你想檢查編譯器對不同版本的C 標(biāo)準(zhǔn)的支持,應(yīng)該參考頁面https://en.cppreference.com/w/cpp/compiler_support。
提及標(biāo)準(zhǔn)和延伸閱讀
在本書中,我們會多次提到C 標(biāo)準(zhǔn)。此文件版權(quán)歸國際標(biāo)準(zhǔn)化組織所有。官方的C 標(biāo)準(zhǔn)文檔可以從這里購買:https://www.iso.org/standard/79358.html。但是,C 標(biāo)準(zhǔn)的多個草案以及相應(yīng)源碼可以在GitHub上免費(fèi)獲得,網(wǎng)址為https://github.com/ cplusplus/draft?梢栽趆ttps://isocpp.org/ std/the-standard鏈接上找到有關(guān)C 標(biāo)準(zhǔn)的更多信息。
C Reference網(wǎng)站是C 開發(fā)人員的一個很好的在線資源,網(wǎng)址為https://en. cppreference.com/。它提供了直接派生自C 標(biāo)準(zhǔn)的C 語言的詳盡文檔。本書多次引用了C 參考中的內(nèi)容。C 參考的內(nèi)容是基于CC-BY-SA協(xié)議的,https://en.cppreference. com/w/Cppreference:Copyright/CC-BY-SA。
(在每一章的末尾,你會發(fā)現(xiàn)一個名為延伸閱讀的部分,該部分包含一份用作參考書目的閱讀材料清單,推薦閱讀以加深對所介紹主題的理解。)
下載示例代碼文件
可以從GitHub上下載本書的示例代碼文件,網(wǎng)址為https://github.com/ PacktPublishing/Template-Metaprogramming-with-CPP。也可以掃描封底二維碼下載。如果代碼有更新,將會在GitHub倉庫中更新它。
下載彩圖
我們還提供了一個PDF文件,其中包含本書中使用的屏幕截圖和圖表的彩圖?梢栽诖颂幭螺d:https://packt.link/Un8j5。也可以掃描封底二維碼下載。
使用的約定
本書使用了一些文本約定。
文本中的代碼:表示文本中的代碼詞匯、數(shù)據(jù)庫表名、文件夾名、文件名、文件擴(kuò)展名、路徑名、虛擬URL、用戶輸入和Twitter用戶名/賬號標(biāo)識。這里有一個例子:這個問題可以通過將init設(shè)置為依賴名稱來解決。
代碼塊的格式如下:
template
structparser:base_parser
{
voidparse()
{
this->init(); // 正確
std::cout<<"parse\n";
}
};
按如下方式編寫任意命令行的輸入或輸出:
fatal error:recursive template instantiation exceeded maximum depth of 1024
use -ftemplate-depth=N to increase recursive template instantiation depth
粗體:表示一個新術(shù)語、一個重要單詞或你在屏幕上看到的單詞。例如,菜單或?qū)υ捒蛑械膯卧~以粗體顯示。這里有一個例子:容量為8,大小為0,頭部和尾部都指向索引0。
提示或重要說明
迭代器概念在第6章概念與約束中進(jìn)行了簡要討論。
本書的參考文獻(xiàn)和問題答案可掃描封底二維碼下載。
馬里烏斯·班西拉(Marius Bancila)于2002年作為一名軟件開發(fā)人員開始了職業(yè)生涯,專注于使用 Visual C 、C# 和 .NET 框架開發(fā)桌面應(yīng)用程序。盡管多年來使用過許多編程和腳本語言(例如 Pascal、C、C 、Java、JavaScript、C#、VB.NET、MC 、C /CLI、HTML、CSS 等),但 C 始終是他的首選語言。目前他在挪威的Visma公司擔(dān)任 ERP 系統(tǒng)的系統(tǒng)架構(gòu)師。
Marius Bancila是Modern C Programming Cookbook和Modern C Challenge等多本C 技術(shù)圖書的作者,熱衷于與他人分享技術(shù)專長,并因此自2006年起連續(xù)18年被授予微軟MVP(最有價值專家)稱號。他撰寫了大量技術(shù)文章,創(chuàng)建和參與了多個開源項目,并活躍于各類在線開發(fā)者社區(qū)。
第Ⅰ部分 模板的核心概念
第1章 模板的簡介 3
1.1 理解模板的必要性 3
1.2 編寫你的第一個模板 6
1.3 理解模板術(shù)語 9
1.4 模板的簡史 10
1.5 模板的優(yōu)缺點 12
1.6 總結(jié) 12
1.7 問題 13
第2章 模板的基礎(chǔ) 15
2.1 定義函數(shù)模板 15
2.2 定義類模板 18
2.3 定義成員函數(shù)模板 20
2.4 理解模板形參 21
2.4.1 類型模板形參 22
2.4.2 非類型模板形參 23
2.4.3 模板模板形參 28
2.4.4 默認(rèn)模板實參 30
2.5 理解模板實例化 32
2.5.1 隱式實例化 32
2.5.2 顯式實例化 35
2.6 理解模板特化 39
2.6.1 顯式特化 39
2.6.2 部分特化 43
2.7 定義變量模板 46
2.8 定義別名模板 49
2.9 探索泛型lambda和lambda模板 51
2.10 總結(jié) 57
2.11 問題 57
第3章 變參模板 59
3.1 理解變參模板的必要性 59
3.2 變參函數(shù)模板 61
3.3 形參包 65
3.4 變參類模板 73
3.5 折疊表達(dá)式 79
3.6 變參別名模板 82
3.7 變參變量模板 84
3.8 總結(jié) 84
3.9 問題 85
第Ⅱ部分 高級模板特性
第4章 高級模板的概念 89
4. 1 理解名稱綁定和依賴名稱 89
4.1.1 兩階段名稱查找 91
4.1.2 依賴類型名稱 94
4.1.3 依賴模板名稱 96
4.1.4 當(dāng)前實例化 97
4.2 探索模板遞歸 99
4.3 函數(shù)模板實參推導(dǎo) 103
4.4 類模板實參推導(dǎo) 112
4.5 轉(zhuǎn)發(fā)引用 117
4.6 decltype說明符 123
4.7 std::declval類型運(yùn)算符 128
4.8 理解模板中的友元關(guān)系 130
4.9 總結(jié) 135
4.10 問題 135
第5章 類型特征和條件編譯 137
5.1 理解和定義類型特征 137
5.2 探索SFINAE及其目的 141
5.3 使用enable_if類型特征啟用SFINAE 145
5.4 使用 constexpr if 149
5.5 探索標(biāo)準(zhǔn)庫類型特征 152
5.5.1 查詢類型類別 152
5.5.2 查詢類型屬性 155
5.5.3 查詢支持的操作 157
5.5.4 查詢類型之間的關(guān)系 158
5.5.5 修改const/volatile說明符、引用、指針或符號 159
5.5.6 各種轉(zhuǎn)換 160
5.6 使用類型特征的實際例子 163
5.6.1 實現(xiàn)拷貝算法 163
5.6.2 構(gòu)建同質(zhì)的變參函數(shù)模板 166
5.7 總結(jié) 167
5.8 問題 168
第6章 概念和約束 169
6.1 理解概念的必要性 169
6.2 定義概念 174
6.3 探索requires表達(dá)式 176
6.3.1 簡單要求 177
6.3.2 類型要求 179
6.3.3 復(fù)合要求 180
6.3.4 嵌套要求 182
6.4 組合約束 183
6.5 了解帶約束模板的順序 187
6.6 約束非模板成員函數(shù) 190
6.7 約束類模板 193
6.8 約束變量模板和模板別名 194
6.9 學(xué)習(xí)更多指定約束的方法 195
6.10 使用概念約束auto形參 196
6.11 探索標(biāo)準(zhǔn)概念庫 198
6.12 總結(jié) 202
6.13 問題 202
第Ⅲ部分 模板的應(yīng)用
第7章 模式和慣用法 205
7.1 動態(tài)多態(tài)和靜態(tài)多態(tài) 205
7.2 奇異遞歸模板模式 208
7.2.1 使用CRTP限制對象實例化的次數(shù) 210
7.2.2 使用CRTP添加功能 211
7.2.3 實現(xiàn)組合設(shè)計模式 213
7.2.4 標(biāo)準(zhǔn)庫中的CRTP 217
7.3 混入 220
7.4 類型擦除 225
7.5 標(biāo)簽派發(fā) 231
7.6 表達(dá)式模板 236
7.7 類型列表 243
7.7.1 使用類型列表 245
7.7.2 實現(xiàn)對類型列表的操作 247
7.8 總結(jié) 253
7.9 問題 254
第8章 范圍和算法 255
8.1 理解容器、迭代器和算法的設(shè)計 255
8.2 創(chuàng)建自定義容器和迭代器 262
8.2.1 實現(xiàn)環(huán)形區(qū)緩沖容器 263
8.2.2 為環(huán)形緩沖區(qū)容器實現(xiàn)迭代器類型 269
8.3 編寫自定義通用算法 275
8.4 總結(jié) 277
8.5 問題 278
第9章 范圍庫 279
9.1 從抽象范圍到范圍庫 279
9.2 理解范圍概念和視圖 281
9.3 理解受約束算法 291
9.4 編寫自己的范圍適配器 294
9.5 總結(jié) 300
9.6 問題 300
附錄A 結(jié)束語 301
以下內(nèi)容可掃描封底二維碼下載
問題答案 303
參考文獻(xiàn) 313