下列程式展示了如何使用max()函式模板
//basics/max.cpp
#include
#include
#include
"max.hpp"
intmain()
在上面的程式中max()被呼叫了三次,每次呼叫的實參型別都不同;一次為int,一次為double,最後一次為std::string。每一次都計算出兩個實參的最大值,而呼叫的結果產生的結果如下
max(7,i):42
max(f1,f2):3.4
max(s1,s2):mathematics
這裡:max()模板每次呼叫前面都加上了有域限定符::,這是為了確認我們呼叫的是全域性名字空間中的max()。因為標準庫也有乙個std::max()模板,在某些情況下也可以被使用因此有時候還會產生二義性。
通常而言,並不是把模板編譯成乙個可以處理任何型別的單一實體;而是對於例項化模板引數的每一種型別,都從模板產生出乙個不同的實體。因此,針對3種型別的每一種,max()都被編譯了一次。例如,max()的第一次被呼叫。
int i = 42;
… max(7,i) …
使用了以int 作為模板引數t的函式模板。因此,它具有呼叫如下**的含義:
inline
intconst
&max
(int
const
& a,
intconst
& b)
補充:這裡用到了inline(內聯函式)
我們知道呼叫乙個任意函式都會為這個函式建立棧空間,如果頻繁的呼叫小函式會消耗大量的棧空間,對記憶體造成很大的壓力,甚至會導致記憶體枯竭。c++為了解決這個問題也就創造了內聯函式,也就是inline。
回到正題,這種用具體型別代替模板引數的過程叫例項化(instantiation)。他產生了乙個模板的例項。
類似的,max()的其他呼叫也將為double和std::string例項化max模板,就像具有如下單獨的宣告和實現一樣:
const double& max(double const&,double const&);
const std::string& max(std::string const&, std::string const&);
如果試圖基於乙個不支援模板內部所使用的操作型別例項化乙個模板,那麼將會導致乙個編譯期錯誤,例如:
std::complex c1, c2;//std::complex並不支援operator <
max(c1,c2) //編譯器錯誤
於是我們可以得出乙個結論:模板被編譯了兩次,分別發生在
1.例項化之前,先檢查模板**本身,檢視語法是否正確:在這裡會發現錯誤的語法,如遺漏分號等。
2在例項化期間,檢查模板**,檢視是否所有的呼叫都有效,這裡會發現無效的呼叫,如該例項化不支援某些函式呼叫等。
Django筆記 模板Templates
django模板語言,簡寫dtl,定義在django.template包中 由startproject命令生成的settings.py定義關於模板的值 常用方式 在專案的根目錄下建立templates目錄,設定dirs值 dirs os.path join base dir,templates 模板...
Django筆記五 模板Templates
常用標籤 1,for for內部允許使用for提供的內建變數 forloop 1,forloop.counter return int 記錄當前迴圈的次數,從1開始 2,forloop.first 返回值為布林型別 是否是第一次迴圈 第一項 3,forloop.last 返回值為布林型別 是否是最後...
C 學習筆記 程式的除錯 assert函式的使用
目標 掌握程式除錯中assert函式的使用 using system using system.collections.generic using system.linq using system.text using system.threading.tasks namespace example...