C++11 模板元編程 - 兩階段的C++語言


前面我們介紹了C++模板元編程的基礎(chǔ)知識(shí)。我們將模板元編程的計(jì)算對(duì)象統(tǒng)一到類型上,引入了元函數(shù)的概念。元函數(shù)是模板元編程的基礎(chǔ)構(gòu)件,它支持默認(rèn)參數(shù),支持高階函數(shù),支持柯里化,遵守不可變性,具有惰性特征。此外我們還介紹了在模板元編程中做計(jì)算控制的模式匹配和遞歸的相關(guān)技巧。

在示例代碼中,我們完成了幾個(gè)模板元編程的基礎(chǔ)元函數(shù):IntType,BoolType,Value,Print,IsEqual,IfThenElse等等,并且對(duì)它們用宏進(jìn)行了封裝,分別是__int(),__bool()__value(),__print(),__is_eq(),__if()。后文在使用的時(shí)候,對(duì)于某一用宏封裝過的元函數(shù),會(huì)提到“元函數(shù)Value”,可能也會(huì)提成“元函數(shù)__value()”,請(qǐng)注意它們是相同的。

在前面的介紹中,我們一直將C++模板元編程看做是一門獨(dú)立的圖靈完備的純函數(shù)式語言。雖然C++模板元編程和我們熟識(shí)的運(yùn)行期C++無論在語法還是計(jì)算模型上都有較大的差異,但他們卻能最緊密無縫地集成在一起。有了模板元編程,我們就可以把C++看成是一門兩階段語言。

第一階段發(fā)生在C++編譯期前段,這時(shí)可以看做是C++模板元編程的天下。此時(shí),C++相當(dāng)于一門純函數(shù)式的解釋型語言,編譯器在此時(shí)充當(dāng)了解釋器的角色,直接面向C++源代碼進(jìn)行解釋執(zhí)行。我們知道對(duì)于代碼最全的元信息就存在于源代碼自身中,所以解釋型語言所謂反射或者自省的能力都非常的強(qiáng),這也是C++模板元編程擁有強(qiáng)大能力的原因之一??蚣芎蛶斓拈_發(fā)往往離不開語言自身擁有的反射能力。C++模板元編程帶來的這種反射能力,和運(yùn)行期C++的RTTI技術(shù)本質(zhì)并不相同,它更加的強(qiáng)大且不會(huì)帶來運(yùn)行時(shí)開銷。STL中的type_traits庫,利用模板元編程技術(shù)定義了非常多的編譯期反射工具,可以直接供大家使用。

第一階段C++模板元編程的另一特殊性在于它的計(jì)算對(duì)象:類型和常量,它們是構(gòu)成運(yùn)行期C++的基本元素。因此模板元編程可以看做是運(yùn)行期C++的代碼生成器。當(dāng)?shù)谝浑A段結(jié)束后,C++編譯器恢復(fù)我們熟識(shí)的角色,針對(duì)第一階段的結(jié)果代碼進(jìn)行編譯,產(chǎn)生可以運(yùn)行的C++程序。正是模板元編程這種可以充當(dāng)運(yùn)行期C++代碼生成器的能力,使得它成為構(gòu)造內(nèi)部DSL的強(qiáng)大工具。

C++在編譯期之前還有一個(gè)預(yù)處理階段。預(yù)處理期可以利用宏完成各種代碼生成,Boost中還專門有一個(gè)關(guān)于預(yù)處理的工具庫preprocessor,用于在預(yù)處理期進(jìn)行數(shù)值運(yùn)算及代碼生成,甚至還定義了預(yù)處理期的數(shù)據(jù)結(jié)構(gòu)和算法。雖然預(yù)處理技術(shù)也是一項(xiàng)非常有用的工具,但由于其原理僅是文本替換,并不做真正的運(yùn)算,所以理論上并非是圖靈完備的,因此我們?cè)谏蠄D中并未將其列入。

由于C++的模板元編程能力是在C++語言引入模板特性后被意外發(fā)現(xiàn)的,所以不像別的經(jīng)過預(yù)先良好設(shè)計(jì)的函數(shù)式語言那樣語法優(yōu)美,功能完備。通過前面的例子確實(shí)也看到它的很多寫法相比Haskell要繁瑣的多,而且功能上也要差很多。在C++11出現(xiàn)之前,標(biāo)準(zhǔn)上對(duì)模板元編程的支持還存在一些大的缺陷,而且不同編譯器對(duì)模板元編程的支持也不太統(tǒng)一。另外我們也看到,模板元編程操作IO的能力非常的差,這導(dǎo)致了模板元編程的問題定位變得困難。

得益于近些年C++標(biāo)準(zhǔn)以及主流編譯器對(duì)C++編譯期計(jì)算支持得越來越完備,使得模板元編程相比以前要更加方便和完善。雖然如此,由于歷史原因,它仍舊無法和一門真正經(jīng)過良好設(shè)計(jì)的語言相比。但由于它內(nèi)置于C++,使得它和運(yùn)行期C++的結(jié)合上有著天然無法替代的優(yōu)勢(shì),這也是我們要學(xué)習(xí)它的原因。不要相信類似 “python + 傳統(tǒng)C++” 的說法,否則你就基本喪失了構(gòu)造靈活高效的C++程序庫和框架的能力。想要成為一名專業(yè)的C++程序員,熟悉模板元編程是必須的。


TLP測(cè)試框架

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 熟悉C++的程序員都知道,C++是一門多范式編程語言,支持面向過程、面向?qū)ο?、泛型編程以及函?shù)式編程范式。然而提到...
    MagicBowen閱讀 7,448評(píng)論 8 18
  • TITLE: 編程語言亂燉 碼農(nóng)最大的煩惱——編程語言太多。不是我不學(xué)習(xí),這世界變化快! 有時(shí)候還是蠻懷念十幾、二...
    碼園老農(nóng)閱讀 5,602評(píng)論 2 35
  • 轉(zhuǎn)自http://blog.csdn.net/xugangwen/article/details/44811783...
    扎Zn了老Fe閱讀 13,098評(píng)論 1 142
  • 簡介 C++98/03的設(shè)計(jì)目標(biāo):一、比C語言更適合系統(tǒng)編程(且與C語言兼容)。二、支持?jǐn)?shù)據(jù)抽象。三、支持面向?qū)ο?..
    認(rèn)真學(xué)計(jì)算機(jī)閱讀 5,521評(píng)論 0 53
  • 認(rèn)識(shí)中島之前山田涼介對(duì)于“窮”是完全沒有概念的。 他生在貧窮的家庭但是他有父母全心全意的愛,雖吃的不好但能吃得飽,...
    xjb寫寫閱讀 481評(píng)論 2 1

友情鏈接更多精彩內(nèi)容