c 函式模板

2021-07-26 12:33:35 字數 4556 閱讀 2429

何為泛型程式設計呢?簡單的說就是,我們按照特定語法寫**,然後讓編譯器去具體實現這些**。而函式模板,就是讓編譯器按照呼叫時的實參自動生成相應的函式版本.

格式如下:

template

returntype functionname(argument-list)

其中templatetypename是關鍵字。

tips:

在c++98之前c++是使用class關鍵字來定義模板的,而在c++98開始使用typename關鍵字定義模板了。

示例:現在假設我們想寫乙個swap函式來交換兩個數的值

#include 

#include

#include"test_h.h"

using

std::string ;

using

std::cout;

using

std::endl;

//function declaration

template

void swap(t& a,t& b);

int main(int argc, char** argv)

編譯器會根據swap()中的引數型別自動生成int和double版本的函式。

node:

記住template在定義和宣告中都是不能少的

假設有如下模板

template

void f(t a,t b)

如果a,b是陣列的話a=b是不可以的

如果a,b是結構的話a>b也是不可以的

所以模板程式設計有時候你要考慮一下引數的特殊性。這時候我們就要用到顯示具體化

格式如下:

template <>returntyoe function

< type>(type, type)

其中template <>為關鍵字,如果編譯器可以根據引數列表推斷模板型別那麼< type>中的type為可選項

示例:

void swap(int a,int b);

template

<>void swap<>(double, double);

template

void swap(t, t);

上賣弄三種分別為非模板函式,模板的顯式具體化,模板函式

如果程式中同時定義了三種函式,會優先呼叫非模板函式,然後模板的顯式具體化,最後模板函式

一開始定義的模板函式swap(t a,t b)它會告訴編譯器生成函式的方式,但是還沒有生成函式,而當呼叫swap(i1,i2)和swap(d1,d2)時就會生成相應的模板例項。模板的顯式具體化也一樣都是不會生成函式例項的,而是出現了具體型別之後再讓編譯器按照模板具體化建立函式例項。

在以前c++只能通過判斷函式引數來例項化函式,這種叫做隱式例項化而現在的c++可以通過顯式例項化了,格式如下

template returntype function

(type,type);

上面的**告訴編譯器建立乙個接受type型別函式的例項,其中template為關鍵字,必須要寫的。

示例:

template

void swap(int,int);//函式例項化

template

<> void swap(int,int);//模板具體化

上面的例項化告訴編譯器使用swap模板生成乙個接受int引數的函式例項,他已經在**中了。

而模板顯式具體化,告訴編譯器當呼叫函式時如果引數為int時,就按照模板具體化定義的形式建立函式。

除了上面的顯示例項化的手段,我們還可以在程式中手動使用函式模板來建立顯示例項化,如下

template

void swap(t a,t b)

……int i=19;

double d=19.0;

cout

(i,d)當同時有非模板函式,模板函式,模板顯示具體化時定義時。會優先呼叫非模板函式,然後模板的顯示具體化,最後模板函式

void f(int);                //#1  

float f(float,float=3); //#2

void f(char) //#3

char * f(const

char *) //#4

char f(const chat *) //#5

template

void f(const t &) //#6

template

void ft *) //#7

如果呼叫

f('b')

上面#3,#5,#6都是原型匹配,但是#3,#5優先於#6,#6優先於#1

template

void f(t a,t b)

所以c++11引入了關鍵字decltype來解決這個問題

int x;

decltype(x) y;//y is int

decltype(x+y) xy;//xy is x+y type

xy=x+y;

decltype(x+y)xy=x+y;//xy is x+y type

上面是三種decltype的簡單使用。而對於如下標準格式

decltype(expression) var;

編譯器會編譯乙個核對表,核對表的簡化版如下

第一步:如果expresssion是乙個沒有用括號的識別符號,則var的型別與該識別符號相同,包括const等修飾符

double x=19.0;

double y=19.0

double &rx=x;

const

double *pd;

decltype (x) w;//w is double

decltype (rx) u;

//u is double &

decltype (pd) v ;

//v const double *

第二步:如果experssion是乙個函式呼叫,var是的型別與函式返回值一樣

int f(int);

decltype( f(3)) m//m is int

note:

這實際不會呼叫函式,編譯器會根據函式原型判斷返回值型別

第三步:如果expression是乙個左值,則var為指向型別的引用。這好像意味著前面w應為引用型別,因為x是乙個左值,但是這種情況下已經在第一步處理過了。要進入第三步expression不能是未用括號括起來的識別符號

double xx=19.0;

decltype((xx))r2=xx;//r2 is double &

devltype(xx)w=xx//w is double

第四步:如果前面條件都不滿足,則var的型別與expression型別相同

int j=3;

int& k=j;

int& n=j;

decltype(j+6) i1;//i1 is int

decltype(100l) i2;

//i2 is long

decltype(k+n) i3;

//i3 is int

templatetype f(t a,t b)
decltype (a+b) 不行嗎?因為這時候還沒有定義a,b,編譯器不知道a,b是什麼。c++11為auto新增了語法功能來解決這個問題,如下

auto f(int i1,int i2)->double;

auto告訴編譯器返回型別在後面寫著。他可以和decltype 連用

auto f(int i1,int i2)->decltype(x+y);

這樣就完成了返回型別的自動換了。

c 函式模板

include using namespace std template t max t a,t b,t c int main int main int i1 185,i2 76,i3 567,i double d1 56.63,d2 90.23,d3 3214.78,d long g1 67854...

c 函式模板

關鍵字template總是放在模板的電腦關於與宣告的最前面,關鍵字後面是用逗號分隔的模板參數列,該列表是模板參數列,不能為空。模板引數可以是乙個模板型別引數,它代表了一種型別 也可以是乙個模板非型別引數,它代表了乙個常量表示式。模板型別引數由關鍵字class或typename後加乙個識別符號構成。在...

C 函式模板

c 提供了函式模板 function template 所謂函式模板,實際上是建立乙個通用函式,其函式型別和形參型別不具體指定,用乙個虛擬的型別來代表。這個通用函式就稱為函式模板。凡是函式體相同的函式都可以用這個模板來代替,不必定義多個函式,只需在模板中定義一次即可。在呼叫函式時系統會根據實參的型別...