c 模版的一些使用方法(三)

2021-06-05 23:26:37 字數 2250 閱讀 3237

c++模版的應用是可以分類的。按照用途,可以分為:

1)工程模版

2)演算法和資料結構的解耦

3)工作於編譯期的模版

4)xx的封裝

5)介面卡模式

首先解釋一下,這裡的劃分屬於較高層的應用劃分,但這些應用都是基於模版的一些共同特性的,比如帶預設引數、特化和偏特化等。

分別解釋一下就是:

(1)工程模版:《c++模版的一些使用方法(一)》中提到修改第三方庫的應用屬於這一類。工程模版主要是在大工程中的一些處理手法,不太好說。

(2)演算法和資料結構的解耦就很清晰了,比如stl庫,find演算法既可以用於vector也可以用於list。再比如經常使用的單件模式,將它宣告為幾類,任何需要是單件模式的類只要從這個基類派生即可獲得單件屬性

templateclass singleton

public:

static t& getinstance()

};class myclass:public singleton{};

(3)工作於編譯期的模版

由**到可執行檔案分為幾個階段:

no.1預處理階段:處理#define,#ifdef,#include等預處理指令。它使在編譯之前提供了一次修改原始檔的機會,具有很大的靈活性。

no.2編譯期:將源**編成機器碼,每個模組生成obj檔案,

no.3鏈結器:將n個obj檔案組合在一起,解析他們之間的交叉關係,得到可執行檔案。

平時我們所說的執行效率,是指可執行檔案處理一組資料的效率,可能還聽說過在程式設計比賽中可以利用預處理來做一些事情,以此減少程式處理資料的時間,那麼同樣,有些事情是可以在編譯期做的,同樣可以通過把一些事情提前到編譯期來提高程式的效率。

首先要明白哪些工作可以在編譯期做:

no.1當有函式過載時,編譯器在編譯期決定呼叫哪個函式;

no.2sizeof操作符,typedef操作符,+ - = < > :?等運算子,等等等

no.3enum型別的賦值

no.4模版的特化、偏特化和例項化

那麼,可以在編譯期做哪些事呢?

我總結的有兩點:

1)計算一些資料

2)生成**

計算資料時,比如,可以這樣計算fibonacci數列:

templatestruct fibonacci;};

template<>

struct fibonacci<1>;};

template<>

struct fibonacci<0>;};

int main()

;

首先定義了乙個模版,還有它的兩個特化(針對1和0),接著呼叫fiboncaai<40>::result,則編譯器在編譯時會嘗試給模版中enum::result賦值,賦的是它後面那個表示式,而後面的表示式是乙個另外兩個模版的例項化,這同樣也發生在編譯期,所以編譯器會繼續跟下去,一直跟到fiboncaai<1>::result+fiboncaai<0>,然後編譯器發現針對1和0是有模版特化的,於是它去呼叫特化,特化中定義了出口,於是賦值結束。可以將其理解為類遞迴,但不同的是,真正意義的遞迴是函式的巢狀呼叫本身,時間複雜度很高,而這裡,由於在編譯器,每次「遞迴」實質上是模版的例項化,而出口是模版的特化,所以不存在任何的函式巢狀呼叫。

上面fiboncaai<40>輸出的結果是102334155,反彙編看一下,如圖:

編譯器經過計算,直接在這裡放了乙個立即數,譯成十進位制正是102334155。

而上面**中所消耗的時間是0。如圖

而經過測試,用普通的函式遞迴計算fiboncaai的第40個,需要8秒的時間。

用於生成**時,也可以成為模版的元程式設計,元程式設計是指某類電腦程式的編寫,這類電腦程式編寫或者操縱其他程式(或者自身)作為它們的資料,或者在編譯時完成部分本應在執行時完成的工作。很多情況下比手工編寫全部**相比工作效率更高。編寫元程式的語言稱之為元語言,被操作的語言稱之為目標語言。一門語言同時也是自身的元語言的能力稱之為反射。

由上面的定義可知,元程式設計也是工作在編譯期,其實上面的計算資料的應用,也可以歸為元程式設計,因為編譯器不斷的例項化模版來「遞迴」,本質上也是在幫我們生成**。loki庫中的typelist就是使用模版元程式設計的經典之作。

xx的封裝和介面卡模式以後再說吧

c 模版的一些使用方法(二)

c 模版的其他技巧 1.編號生成器 考慮下面的場景,對於int char double bool float這5種型別,我們希望對他們進行型別編號1 5,並且確保對於每種型別,它的編號不會改變,即每次呼叫函式獲取該編號時,他都是唯一的且不變的。那麼使用通過定義乙個模版函式實現。int g id 0 ...

DateTime的一些使用方法

1 datetime 數字型 system.datetime currenttime new system.datetime 1.1 取當前年月日時分秒 currenttime system.datetime.now 1.2 取當前年 int 年 currenttime.year 1.3 取當前月 ...

define的一些使用方法

1.可以對一些常量 字串進行巨集定義,在預處理過程中進行替換,而不是在編譯過程中。define pi 3.1415926 2.也可以對資料型別進行巨集定義,這樣與 typedef 效果相同 typedef為 c語言的關鍵字,作用是為一種資料型別定義乙個新的名字。typedef unsigned ch...