1 模板元編程(TMP)技術(shù)
在C++程序設(shè)計(jì)語言中,模板元編程是實(shí)現(xiàn)代碼重用的一種重要機(jī)制。下面首先對(duì)模板元編程技術(shù)進(jìn)行介紹,然后給出TADA方法中需要使用的幾個(gè)基本的模板元程序。
1.1 模板元編程簡介
模板可以將類型定義為參數(shù),以提高代碼的可重用性。模板包括類模板和函數(shù)模板等。函數(shù)模板與模板函數(shù)的區(qū)別可以類比于類與對(duì)象的區(qū)別:函數(shù)模板是模板的定義;而模板函數(shù)是函數(shù)模板的實(shí)例,具有程序代碼,占用內(nèi)存空間。當(dāng)編譯系統(tǒng)發(fā)現(xiàn)了函數(shù)模板一個(gè)對(duì)應(yīng)的函數(shù)調(diào)用后,根據(jù)實(shí)參的類型來確認(rèn)是否匹配函數(shù)模板中對(duì)應(yīng)的形參,然后生成一個(gè)重載函數(shù),稱該重載函數(shù)為模板函數(shù)。類似地,在聲明了一個(gè)類模板后,也可以創(chuàng)建類模板的實(shí)例一模板類。
類模板的一般形式如下:
template
class類名{
//類定義…
};
C++模板系統(tǒng)能夠通過模板的特化、偏特化實(shí)現(xiàn)邏輯判斷,并能通過模板遞歸實(shí)現(xiàn)循環(huán),構(gòu)成了一個(gè)圖靈完全的二級(jí)語言。使用這種二級(jí)語言進(jìn)行編程叫作C++模板元編程(Template Meta Programming,TMP)。模板元編程的驅(qū)動(dòng)力是模板的遞歸實(shí)例化。
下面給出C++模板元編程的一個(gè)示例。
首先定義一個(gè)類模板,通過該類模板可實(shí)現(xiàn)在編譯期間計(jì)算4的任意次方。如下所示:
通過下面的程序來使用該模板。
程序Test.cpp執(zhí)行完后,會(huì)正確輸出4的7次方的值,該數(shù)值是C++編譯器在編譯模板元程序時(shí)遞歸計(jì)算得到。由于模板元程序完全在編譯期間執(zhí)行,相當(dāng)于對(duì)編譯器功能進(jìn)行擴(kuò)充,因而利用這種程序進(jìn)行量綱檢測具有良好的可行性。
1.2 基本模板元程序
下面給出TADA方法中需要使用的幾個(gè)基本的模板元程序。
(1)靜態(tài)判斷
語法:StaticlF<cond,T1,T2>::ResultType
語義:當(dāng)cond為真時(shí),ResuhType為T1,否則ResuhType為T2。
(2)靜態(tài)斷言
語義:當(dāng)cond為真時(shí)什么也不做,否則產(chǎn)生一個(gè)編譯期錯(cuò)誤(UnitError沒有定義,或void函數(shù)不應(yīng)該有返回值)。
(3)靜態(tài)絕對(duì)值
語義:遞歸的使用輾轉(zhuǎn)相除法在編譯期間求出a與b的最大公約數(shù),其中a與b為int類型。
2 TADA量綱檢測方法
TADA量綱檢測方法需要涉及到單位和量綱的表示、計(jì)算、標(biāo)注以及數(shù)學(xué)運(yùn)算函數(shù)的量綱包裝等各個(gè)組成步驟,下面將依次對(duì)其進(jìn)行介紹。
2.1 單位和量綱的表示
在Osprey方法中,量綱是用一個(gè)長度為7的向量表示的,每個(gè)分量對(duì)應(yīng)一個(gè)SI標(biāo)準(zhǔn)量綱。TADA方法中也采用了這種方式。為了簡化闡述,本文只討論長度、重量、時(shí)間這三種量綱,其SI單位分別為米、千克和秒(TADA方法可直接推廣到其他各種量綱)。由于TMP程序的特殊性,它并沒有數(shù)組或向量的支持,也不能使用浮點(diǎn)數(shù)據(jù)(使用浮點(diǎn)數(shù)表示量綱也會(huì)帶來不精確性),量綱在TMP程序中的表示形式有所不同:用u11,u12,u21,u22,u31,u32之類的整型量分別表示,并輔以ratio表示同量綱、不同單位之間的比值,如分鐘和秒的比值為60。
TADA方法可靜態(tài)地建立如下常用單位:
模板元程序在計(jì)算公式的時(shí)候需要推導(dǎo)出新的量綱,例如在計(jì)算的時(shí)候,編譯器應(yīng)該能根據(jù)等號(hào)右邊的公式計(jì)算出它的量綱,并與e的量綱進(jìn)行比較判別。TADA方法的量綱是用分?jǐn)?shù)形式表示的,在每次量綱計(jì)算之后都需要進(jìn)行分?jǐn)?shù)的約分處理,才能進(jìn)行相等性判斷,因而TADA方法可用如下的方式處理新生成單位,如下所示。
2.2 單位和量綱的計(jì)算
由于量綱都是用分?jǐn)?shù)表示的,因而其計(jì)算會(huì)稍有麻煩。下面定義TADA方法中量綱分?jǐn)?shù)的加、減、乘、除和等價(jià)測試運(yùn)算。
(1)分?jǐn)?shù)的加法運(yùn)算,如下所示。
(2)分?jǐn)?shù)的減法運(yùn)算。TADA方法通過加法實(shí)現(xiàn)減法計(jì)算,如下所示。
語義:分?jǐn)?shù)相減并約分,即:
(3)單位相乘。分別將3個(gè)量綱分?jǐn)?shù)相加,然后使用BuildUnit生成新單位。
語義:單位Ua與單位Ub相乘后的新單位。
(4)單位相除。與乘法處理方式相似。
語義:若單位ua與單位Ub等價(jià)則不產(chǎn)生任何效果,否則產(chǎn)生編譯期錯(cuò)誤。
2.3 單位和量綱標(biāo)注的原理和語法
與Osprey等方法類似,TADA方法也在待檢測源程序進(jìn)行單位標(biāo)注,以使得檢測器能夠知道每個(gè)變量的單位。由于經(jīng)過單位標(biāo)注的待檢測程序仍然是合法的可編譯的程序,所以標(biāo)注信息必須由語言自身已有的語法要素構(gòu)成;標(biāo)注信息還不能影響被標(biāo)注變量的任何計(jì)算特性及使用方式,只有滿足這兩點(diǎn)要求的標(biāo)注方式才能使標(biāo)注工作量最小化。此外,已標(biāo)注變量應(yīng)該禁止從未標(biāo)注變量進(jìn)行各種隱含的類型轉(zhuǎn)換,這樣嚴(yán)格的限制才能有效進(jìn)行單位量綱的匹配檢測。對(duì)于C++語言來說,可以采用模板類的方式實(shí)現(xiàn)。
標(biāo)注實(shí)質(zhì)上是把語言原始的數(shù)據(jù)類型替換成TADA方法預(yù)定義的模板類,而模板類實(shí)現(xiàn)了各種運(yùn)算符號(hào)的重載,同時(shí)禁止了任何隱含的類型轉(zhuǎn)換,使得量綱標(biāo)注既滿足語法要素的要求,又滿足計(jì)算兼容性的要求和禁止隱含轉(zhuǎn)換的要求。TADA方法中標(biāo)注的實(shí)現(xiàn)如下所示。
2.4 定義單位量綱
量綱檢測系統(tǒng)應(yīng)該預(yù)定義常用單位量綱,以方便應(yīng)用開發(fā)人員使用。TADA方法采用如下方式定義單位量綱:
2.5 數(shù)學(xué)運(yùn)算函數(shù)的量綱包裝
對(duì)于指數(shù)、對(duì)數(shù)、三角函數(shù)等已有的數(shù)學(xué)運(yùn)算函數(shù),其參數(shù)與返回值都是沒有單位量綱的,不能直接用于有量綱的公式計(jì)算。針對(duì)這個(gè)問題,.TADA方法提供了這些函數(shù)的量綱包裝,以sqrt和sin為例如下:
2.6 輔助工具
TADA方法還提供了一些輔助工具,用于將量綱變量以適合閱讀的方式顯示出來,例如:
可以得到這樣的輸出結(jié)果:0.2米/秒2
2.7 分析和評(píng)估
在TADA方法的基礎(chǔ)上,實(shí)現(xiàn)了面向C/C++程序的量綱檢測系統(tǒng)(TADA系統(tǒng)),并對(duì)TADA系統(tǒng)的檢測能力進(jìn)行了分析和評(píng)估。
首先采用TADA系統(tǒng)來檢測下面的樣例程序。
在TADA系統(tǒng)中,Visual Studio 2003編譯該程序會(huì)出現(xiàn)類似如下的錯(cuò)誤信息,錯(cuò)誤信息的第3行就表明了unit.epp的第9行有錯(cuò)誤。
在檢測能力方面,采用文獻(xiàn)的樣例程序?qū)A-DA系統(tǒng)和Osprey系統(tǒng)的量綱檢測能力進(jìn)行了對(duì)比評(píng)估。在文獻(xiàn)中,Osprey共找到了3個(gè)錯(cuò)誤,其中前2個(gè)是單位誤用錯(cuò)誤,第3個(gè)是單位轉(zhuǎn)換比例因子錯(cuò)誤。TADA系統(tǒng)也完全找到了前2個(gè)錯(cuò)誤,而第3個(gè)錯(cuò)誤在標(biāo)注時(shí)被避免掉了,因?yàn)樵搯挝幌到y(tǒng)包含了量綱之間的比例因子,能夠進(jìn)行自動(dòng)的單位轉(zhuǎn)換。
在性能和可擴(kuò)展性方面,TADA系統(tǒng)能夠更有效地實(shí)現(xiàn)對(duì)c/c++程序的量綱檢測。Osprey系統(tǒng)引入了具有較高計(jì)算復(fù)雜度的線性方程組求解步驟,需要很大的計(jì)算和時(shí)間開銷來解線性解方程組。TADA系統(tǒng)基于模板元編程技術(shù),只需要利用語言自身的語法能力,靠編譯器進(jìn)行單位量綱檢查,沒有帶來太多額外的復(fù)雜計(jì)算。并且TADA系統(tǒng)不會(huì)帶來任何程序的運(yùn)行時(shí)開銷。因此TADA系統(tǒng)可適用于各種規(guī)模的C/C++程序,具有更好的性能和可擴(kuò)展性。
在易用性方面,TADA系統(tǒng)的標(biāo)注負(fù)擔(dān)與Osprey系統(tǒng)相當(dāng)。由于TADA系統(tǒng)利用C++編譯器的功能進(jìn)行錯(cuò)誤檢測,而C++編譯器遇到模板錯(cuò)誤時(shí)的錯(cuò)誤信息卻不很直觀,錯(cuò)誤報(bào)告的可讀性較弱,但仍可以快速定位到錯(cuò)誤點(diǎn)。
3 結(jié) 語
這里提出一種新穎的基于模板元編程的單位量綱檢測方法TADA,并基于該方法實(shí)現(xiàn)了一個(gè)單位量綱檢測系統(tǒng)。
TADA方法采用模板元編程技術(shù),使得經(jīng)過單位量綱標(biāo)注的受測程序仍然是一個(gè)完整、合法、可編譯的C/C++程序,無需維護(hù)多套程序代碼,也無需進(jìn)行復(fù)雜的解方程組運(yùn)算,就能夠在程序代碼中發(fā)現(xiàn)量綱錯(cuò)誤,具有良好的實(shí)用性和可擴(kuò)展性,可以有效適用于多種規(guī)模程序的量綱檢測。
北京2022年10月18日 /美通社/ -- 10月14日,國際數(shù)據(jù)公司(IDC)發(fā)布《2022Q2中國軟件定義存儲(chǔ)及超融合市場研究報(bào)告》,報(bào)告顯示:2022年上半年浪潮超融合銷售額同比增長59.4%,近5倍于...
關(guān)鍵字: IDC BSP 數(shù)字化 數(shù)據(jù)中心東京2022年10月18日 /美通社/ -- NIPPON EXPRESS HOLDINGS株式會(huì)社(NIPPON EXPRESS HOLDINGS, INC.)旗下集團(tuán)公司上海通運(yùn)國際物流有限公司(Nipp...
關(guān)鍵字: 溫控 精密儀器 半導(dǎo)體制造 BSP要問機(jī)器人公司哪家強(qiáng),波士頓動(dòng)力絕對(duì)是其中的佼佼者。近來年該公司在機(jī)器人研發(fā)方面獲得的一些成果令人印象深刻,比如其開發(fā)的機(jī)器人會(huì)后空翻,自主爬樓梯等。這不,波士頓動(dòng)力又發(fā)布了其機(jī)器人組團(tuán)跳男團(tuán)舞的新視頻,表演的機(jī)器人包括...
關(guān)鍵字: 機(jī)器人 BSP 工業(yè)機(jī)器人 現(xiàn)代汽車