C++11 模板元編程 - 前言


熟悉C++的程序員都知道践美,C++是一門多范式編程語言,支持面向過程找岖、面向對象陨倡、泛型編程以及函數(shù)式編程范式。然而提到C++模板元編程许布,在很多人心里這卻是C++里的黑魔法:它很難學習兴革,一旦進入這個領域曾經那些熟悉的東西(if,for...)都不再靈驗爹脾;它很強大帖旨,但現(xiàn)實中卻鮮見有人用它來解決實際問題,除過偶爾在一些編碼練習中被某些C++狂熱粉當做奇淫巧技拿出來秀秀肌肉灵妨。

其實模板元編程是C++所支持的一種非常強大的計算能力解阅,它是使用C++開發(fā)高質量庫和框架所離不開的一項武器。

掌握C++模板元編程泌霍,至少可以在以下場合幫助到你:

  • 實現(xiàn)高擴展性货抄,并且兼具高性能的庫
  • 實現(xiàn)靈活且易于使用的框架
  • 實現(xiàn)基于C++的內部DSL(Domain Specific Language)
  • 幫助更深入地理解并使用模板和泛型編程,更好地去使用C++ STL庫中的高級特性

如果你是一個C++的庫或框架的開發(fā)者朱转,了解和掌握一些模板元編程的知識蟹地,可以讓你的作品更易于擴展、擁有更易用的接口藤为,甚至更高的運行時效率怪与。而即使你只使用C++設計和開發(fā)應用程序,了解模板元編程也會幫助你更好的去使用STL庫的各種特性缅疟,幫助你的局部設計做的更加漂亮分别。

實際上C++模板元編程技術已經滲透在我們日常使用的各種庫和框架中遍愿,例如我們最常使用的STL庫以及各種xUnit測試框架和mock框架≡耪叮可以說沼填,模板元編程是中級C++程序員邁向高級的必經之路!

然而現(xiàn)實是括授,C++模板元編程的學習之旅卻并不平坦坞笙。

一方面,由于C++模板元編程的本質是函數(shù)式編程荚虚,熟練掌握并使用函數(shù)式編程的程序員比較小眾薛夜,絕大多數(shù)程序員初次進入這個領域時面對模式匹配、遞歸和不可變性時都會手足無措曲管。另一方面却邓,由于C++的模板元編程能力是被意外發(fā)現(xiàn)的,不像別的函數(shù)式編程語言經過良好的設計院水,所以C++的這種函數(shù)式計算能力天生存在著各種缺陷腊徙,直到C++11標準才開始逐漸完善起來。在之前很多重要特性都靠很繞的方式去迂回實現(xiàn)檬某,增加了學習的難度撬腾。

另外,市面上介紹模板元編程的書和資料也乏善可陳恢恼,以下的書相對還不錯民傻,但對于模板元編程的介紹仍舊存在一些問題:

  • 《C++ Templates Complete》
    介紹C++模板知識最全面的一本書,涉及到了模板各個方面的基礎知識和應用技巧场斑。由于元編程并不是此書重點漓踢,所以僅有短短一章列舉了一些利用模板元編程做數(shù)值計算的例子。現(xiàn)實中使用模板元編程單純做數(shù)值計算的場合并不多漏隐,模板元編程更大的價值在于做類型計算和代碼生成喧半,書中卻涉及甚少。

  • 《Modern C++ Design》
    介紹如何使用模板進行C++高階設計的一本書青责。介紹了TypeLists的概念挺据,作為一種重要的編譯時數(shù)據(jù)結構,是元編程的基礎脖隶。但遺憾作者并沒有明確的提出元編程的概念扁耐,也沒有對C++編譯時的運算特征進行總結和提煉。最后由于此書基于的C++ 98標準對于模板以及編譯期類型計算支持上的欠缺产阱,書中介紹的不少實現(xiàn)比較迂回復雜婉称。

  • 《C++模板元編程》
    正式介紹C++模板元編程的一本書,引入了元函數(shù)的概念。通過對模板計算的規(guī)范化王暗,發(fā)揮了編譯期元函數(shù)可組合的優(yōu)勢榨乎。遺憾的是,此書只能算是boost中mpl庫的用戶手冊瘫筐,基本上是在講mpl庫的用戶接口和使用方法,沒有涉及庫的實現(xiàn)細節(jié)☆硪Γ現(xiàn)實中我們采用元編程解決問題策肝,一般不會引用boost這么重的庫,往往只會在某一局部借鑒類似的設計技巧隐绵。所以對于元編程來說之众,授之以漁的意義遠大于授之以魚。另外由于boost mpl庫中用了大量C++預處理期代碼生成技術依许,導致通過閱讀mpl源碼去掌握模板元編程的同學一上來就陷入到一堆宏中棺禾,對于學習元編程增加了非常多的干擾因素。

基于以上原因峭跳,我基于C++11標準實現(xiàn)了一個模板元編程的基礎庫:TLP (https://github.com/MagicBowen/tlp)膘婶,然后再通過本手冊來為大家全面介紹C++模板元編程的基本知識和使用技巧。

TLP庫包含以下內容:

  • 基本的編譯期數(shù)據(jù)類型和算法蛀醉;
  • 基本的編譯期數(shù)據(jù)結構TypeList悬襟,以及針對它的各種基本算法函數(shù):length、append拯刁、erase脊岳、replace、unique垛玻、belong割捅、comb...
  • 基于TypeList的各種高階函數(shù),如 any帚桩,all亿驾,sort、transform朗儒、map颊乘,filter,fold...
  • 輔助模板元編程的常用函數(shù)醉锄,如 __is_eq()乏悄,__if(),__print() ...
  • 一些有用的編譯期Traits工具恳不,如 IsBaseOf檩小,IsConvertible,IsBuiltIn...
  • 一些常用的元編程模式烟勋,如 “元函數(shù)轉發(fā)”等规求;
  • 一個面向模板元編程的測試框架筐付,用它描述的所有測試用例執(zhí)行在C++的編譯期,我們使用它來對TLP進行測試阻肿;

除此之外瓦戚,TLP庫中還包含了如下示例代碼,用來演示如何在現(xiàn)實場景中應用好模板元編程和TLP庫:

  • 示范了如何使用模板元編程做純編譯期計算丛塌,完成一個自動數(shù)三角形的程序较解;
  • 示范了如何使用模板元編程技術來實現(xiàn)代碼生成,自動創(chuàng)建visitor設計模式赴邻;
  • 示范了如何使用模板元編程技術來實現(xiàn)一個DSL印衔,用于描述并生成有限狀態(tài)機;

上面提到的TypeList以及使用代碼生成來創(chuàng)建visitor設計模式的原創(chuàng)者是《Modern C++ Design》的作者Andrei Alexandrescu姥敛。在TLP中我用C++11對TypeList及其算法進行了改寫奸焙,并進行了高階函數(shù)的擴展。得益于C++11標準對模板元編程的更好支持彤敛,新的實現(xiàn)比起原來的更加清晰和簡潔与帆。

示例代碼中利用模板元編程創(chuàng)建有限狀態(tài)機DSL的設計最初來自于《C++模板元編程》一書,為了讓其更好被理解墨榄,我對例子以及代碼進行了較大的改編鲤桥。

除了上面的例子,本手冊中還介紹了我自己開發(fā)的針對C++模塊和子系統(tǒng)FT(Functional Test)級別的測試框架dates渠概,展示了它如何使用模板元編程來進行類型萃取茶凳、類型選擇以及類型校驗,最終使得框架變得更易用播揪、更高效以及更安全贮喧。這些技巧可以幫助到大家更好地使用模板元編程去解決現(xiàn)實問題。

最后猪狈,TLP庫自身的測試通過一個原創(chuàng)的C++模板元編程測試框架箱沦。該框架專門針對C++編譯期計算進行測試,它的用法和常見的xUnit測試框架類似雇庙,但有趣的是使用該框架描述的所有測試用例的執(zhí)行發(fā)生在C++編譯期谓形。本文會專門介紹該框架的一些實現(xiàn)細節(jié)。


C++模板元編程當年被提出來的時候疆前,函數(shù)式編程還沒有像今天這樣被更多的人所了解和接受寒跳,當時的C++標準和編譯器對模板和編譯期計算的支持也存在著很多缺陷。然而到了今天竹椒,很多事情發(fā)生了變化童太!本文的讀者最好能夠有一些函數(shù)式編程的基礎,了解C++模板的基本用法,熟悉一些C++11標準的內容书释。當然文中所有用的到模板技術翘贮、C++11標準和涉及到的函數(shù)式編程概念也都會專門介紹和說明。

如果你從來沒有接觸過C++模板元編程爆惧,那么最好從一開始就把它當做一門全新的語言去學習狸页,從頭掌握C++中這種不一樣的計算模型和語法。這種新的語言和我們熟識的運行期C++在語法和計算模型上都有較大的差異扯再,但它的優(yōu)勢在于能和運行期C++緊密無縫地結合在一起肴捉,無論是在提高程序可擴展性還是提高程序運行效率上,都能創(chuàng)造出非常不可思議的效果來叔收。希望通過本手冊,可以讓更多的人掌握C++模板元編程這一設計利器傲隶,在適合的場合下以更有效饺律、更酷的方式去解決問題。

文中出現(xiàn)的所有代碼片段跺株,如果在注釋中給出了TLP庫中對應的文件路徑复濒,則都能在TLP庫中找到源碼。除此之外的其它代碼則是為了文章需要所構造的臨時代碼乒省。另外巧颈,為了減少干擾,本文中所示TLP庫中的代碼均沒有加命名空間袖扛,閱讀文章和TLP庫源碼時請注意區(qū)分砸泛。


模板的基礎知識

返回 C++11模板元編程 - 目錄

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蛆封,隨后出現(xiàn)的幾起案子唇礁,更是在濱河造成了極大的恐慌,老刑警劉巖惨篱,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盏筐,死亡現(xiàn)場離奇詭異,居然都是意外死亡砸讳,警方通過查閱死者的電腦和手機琢融,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來簿寂,“玉大人漾抬,你說我怎么就攤上這事〕K欤” “怎么了奋蔚?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我泊碑,道長坤按,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任馒过,我火速辦了婚禮臭脓,結果婚禮上,老公的妹妹穿的比我還像新娘腹忽。我一直安慰自己来累,他們只是感情好,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布窘奏。 她就那樣靜靜地躺著嘹锁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪着裹。 梳的紋絲不亂的頭發(fā)上领猾,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天,我揣著相機與錄音骇扇,去河邊找鬼摔竿。 笑死,一個胖子當著我的面吹牛少孝,可吹牛的內容都是我干的继低。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼稍走,長吁一口氣:“原來是場噩夢啊……” “哼袁翁!你這毒婦竟也來了?” 一聲冷哼從身側響起婿脸,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤梦裂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后盖淡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體年柠,經...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年褪迟,在試婚紗的時候發(fā)現(xiàn)自己被綠了冗恨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡味赃,死狀恐怖掀抹,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情心俗,我是刑警寧澤傲武,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布蓉驹,位于F島的核電站,受9級特大地震影響揪利,放射性物質發(fā)生泄漏态兴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一疟位、第九天 我趴在偏房一處隱蔽的房頂上張望瞻润。 院中可真熱鬧,春花似錦甜刻、人聲如沸绍撞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽傻铣。三九已至,卻和暖如春祥绞,著一層夾襖步出監(jiān)牢的瞬間非洲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工就谜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人里覆。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓丧荐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親喧枷。 傳聞我的和親對象是個殘疾皇子虹统,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內容