template t fun(t val1, t val2)
開頭的template
表示接下來的函式是乙個模板函式
其中的typename
也可以用class
來替代.
t
在之後的函式裡可以用來代指函式型別.你也可以把它改成其他名字,然後用到它的地方也改成對應的名字就行.
總之,必須以template
這個關鍵字開頭,後面乙個或者
,
t
只是乙個識別符號,不是固定搭配,可以任意寫.
再之後就是寫你想要的函式.
要注意,函式裡用到的操作符對於傳進去的引數的型別必須要合法
例如, 如果傳進去乙個string
,那裡面就不能對這個變數用減號-
,因為string
沒有減法.(編譯器可以發現這個錯誤,所以這樣的**是編譯不過的)
c++的max()
等函式使用了這種方式,所以你會發現max()
的兩個引數必須相同.
在編譯的時候,編譯器會用具體的型別來代替型別模板引數,這個過程叫做例項化.
其實就是生成指定了實際型別的函式,來替換模板函式.
但是只會生成需要的型別,而不是每種型別都來乙個.
對於以上的那個模板函式,程式在編譯的時候,會檢查這個函式在**中被傳入了什麼型別,然後對於每種用到的型別,生成乙個函式來替換原來的模板函式.
例如,如果程式中的main
如下:
int main()
那麼就只會生成int fun(int a, int b)
和double fun(double a, double b)
.
你可以在模板函式裡用多個型別,形狀如下
template void fun(x tv1, y tv2)
這時,呼叫像這樣fun(1, 2.0)
.
但是使用多個型別的時候,編譯器不一定能推測出到底是哪個對應什麼型別,例如
template z fun(x a, y b)
如果你這樣呼叫int tmp = fun(1, 2.0)
, 就會執行錯誤,因為編譯器推測不出z
是什麼型別.
所以你應該在呼叫的時候,通過尖括號指定型別,像這樣int tmp = fun(1, 2.0)
.
其實我們可以只指定推測不出來的型別,而不指定能夠推測的型別.
要怎麼做,我們可以把推測不出來的型別放到最前面,如下
template z fun(x a, y b)
那麼我們可以這樣呼叫int tmp = fun(1, 2.0)
.
尖括號裡面只要寫乙個int
,用來指定推測不出來的z
就好了.
注意,一定要把需要指定的引數堆到最前面,不能跳著指定的.
很多時候,推測不出的是返回值,我們可以用auto
代替返回值,形狀如下
templateauto fun(x x, y y)
有這樣一種操作
templateauto fun(x x, y y) -> decltype(x*y)
這裡auto
並沒有進行型別推導.
有時候乙個模板函式本身已經有能力推測出所有型別了,我們沒有必要再加尖括號.
但如果存在乙個同名的普通函式fun(int a, int b)
, 那麼這樣呼叫fun(1,2)
的時候,就會優先呼叫普通函式.
如果我們加乙個尖括號fun<>(1, 2)
,雖然沒有含義,但是可以讓它呼叫模板函式.
c 函式模板1
1 定義 函式模板 只適用於引數個數相同但是型別不同 而且函式體相同的情況 2 這個例子沒有使用模板的情況 include using namespace std void swap int a,int b void swap double a,double b intmain1 3 使用模板以後 ...
C 函式模板(1)
如下 所示,幾個函式間在函式體一致或者是相差不大是時,就是資料型別不一樣,如是單獨寫三個函式,會有一點麻煩,這時,提供乙個函式模板 抽離出引數列表中不一樣的部分 會使得編寫過程不至於枯燥繁瑣,也使得後期修改更加方便。int max int a,int b int max double a,doubl...
C 模板程式設計 函式模板 類模板
通常int sum int a,int b 這裡的兩個形參變數a b,就是為了接受實參的值。而模板的意義就在於此,模板就是針對型別的,使型別也可以進行引數化,即由原來的的固定的轉化為可變的。模板的意義 對型別也可以進行引數化了 裡面的內容不進行編譯,型別不知道 1 定義乙個模板形參列表 templa...