999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

C++函數模板的模板參數類型轉換技術

2014-11-06 14:08:08何遠強李全艷彭海平龔紅仿
科技創新導報 2014年10期

何遠強++李全艷++彭海平++龔紅仿

摘 要:模板是C++為用戶提供的一種功能非常強大的、能方便的實現類屬編程的工具。該文討論了利用重載函數模板的方法實現模板參數類型的顯式轉換機制,并闡明了在實際應用中必須注意的問題。

關鍵詞:C++ 函數模板 重載函數 模板參數 類型轉換

中圖分類號:TP312 文獻標識碼:A 文章編號:1674-098X(2014)04(a)-0019-02

模板是C++為用戶提供的一種功能非常強大的、能方便的實現類屬編程的工具,它允許用戶構造類屬函數——模板函數。但在實際編程中,我們并不是直接定義模板函數,而是定義一類函數的抽象——函數模板,它以任意的數據類型T為參數及函數返回值,用將T實例化的模板參數再實例化函數模板,所得的函數就是模板函數。因而,函數模板并不是一個完全的函數,而是代表一類函數,只有用模板參數實例化后成為模板函數,才能完成具體的函數功能。

1 問題的提出

在模板函數實例化為函數模板時,盡管模板參數T可以實例化成各種類型,但是采用模板參數T的各參數之間必須保持完全一致的類型。我們先看下面的例子:

template

T max(T x,T y)

{ return (x>y)?x:y;

}

void main()

{ int i=10;

char c=a;

float f=4.374;

cout<

cout<

cout<

cout<

cout<

cout<

cout<

}

在上面的例子中,定義的函數模板是比較兩個數的大小,數據類型既可以是系統預定義類型,也可以是用戶自定義類型。這里,由函數模板生成了三個模板函數,分別是用模板實參int、char、float將類型參數T實例化而得。

我們可以看出,只有當參數類型完全一致時,得到的模板函數才是正確的。當參數類型不一致時,例如 max(i,c),系統將提醒我們找不到與max(int,char)相匹配的函數定義。然而,在C++中,int類型和char類型之間、flot類型與int類型之間、float類型與double類型之間等,都可以隱式轉換,而且這種轉換是非常普遍的。因而,完全可以把函數max(int,char)認為是函數max(int,int)。但是,模板類型沒有這種識別能力,不具有隱式類型轉換的功能。

在實際編程的過程中,經常會使用函數模板解決功能相同的一類問題,既可以大大減少程序代碼、避免重復的定義,又可以增強程序的清晰性和可讀性,這就涉及到如何實現模板參數類型轉換機制的問題。

2 重載模板函數

解決這個問題的方法是允許函數模板參與重載,即可以用非模板函數重載一個同名的函數模板,有兩種表述方式:

其一,利用函數模板的函數體。非模板函數對函數模板的重載定義是通過借用函數模板的函數體。需要定義重載時,只需聲明,不用給出函數體,當執行此重載版本時會自動調用函數模板的函數體。例如,在上例中,可以作如下聲明:

int max(int,int);

這樣就完成了重載聲明,此重載函數雖然借用了函數模板的函數體,但它支持數據類型間的隱式轉換。經過這樣和重載定義后,使得max(int,char), max(char,int), max(float,int), max(int,float), max(double,int), max(double,float)等一系列函數變成為合理的和正確的調用。

其二,重新定義函數體。對于要重新定義函數體的重載函數,所帶參數的類型可以隨意,就像一般的重載函數一樣定義。例如,在上例中,比較兩個字符串的大小,可以重栽定義如下:

char *max(char *x,char *y)

{return(strcmp(x,y)>0)?x:y;}

但是,在一個實際的函數調用時,它既可以和一個重載函數相匹配或是參數隱式轉換后與某一重載函數相匹配,又可以與某一模板函數相匹配。究竟調用哪一個函數,需按照一定的規則安排先后次序。這些規則就是函數模板與同名的非模板函數的重載在調用時均需遵循的約定:

(1)首先尋找一個參數完全匹配的函數,如果找到了就調用它。

(2)在(1)失敗后,尋找一個函數模板,使其實例化,產生一個匹配的模板函數,若找到了,就調用它。

(3)在上面均失敗后,再試一試低一級的對函數的重載方法,即通過類型轉換可產生參數匹配,若找到了,就調用它。

(4)若以上均失敗,則得出是一個錯誤調用的判定。

我們看一個重載函數模板的例子,根據上面的規則來判斷各函數的調用情況:

#include

#include

template //定義函數模板

T max(T x,T y)

{ cout<<"This is a template function! The max is: ";

return (x>y)?x:y;

}

class point //定義類類型

{ float x,y;

public:

point(float x=0,float y=0);

float getx(){return x;}

float gety(){return y;}

float point_sqrt();

friend int operator>(point px,point py); //用友元重載”>”運算符

}

//point類成員函數定義

point::point(float x,float y)

{ point::x=x;

point::y=y;

}

float point::point_sqrt()

{ return sqrt(x*x+y*y);}

int operator>(point px,point py)

{ if (px.point_sqrt()>py.point_sqrt()) return 1;

else return 0;

}

//重載函數定義

int max(int x,int y) //重新定義函數體

{ cout<<"This is the overload function with int,int! The max is: ";

return (x>y)?x:y;

}

char max(int x,char y) //重新定義函數體

{cout<<"This is the overload function with int,char! The max is:";

return (x>y)?x:y;

}

void func(int i,char c,float f)

{cout<

cout<

cout<

cout<

cout<

cout<

}

void main()

{ int i; char c; float f;

…… //輸入i,c,f

func(i,c,f); //調用func函數實現模板參數類型的轉換

point pa(2,5),pb(3,4),pc;

pc=max(pa,pb); //調用模板函數用point類類型實例化

cout<<"("<

cout<

}

我們分析上面的程序,在主函數main()中,調用func(i,c,f)函數。在func(i,c,f)函數中調用max(i,i)時,由于兩個參數均為整型,按照規則,首先查找完全匹配的函數進行調用,因此它調用的是int max(int,int)重載版本。

調用max(c,c)時,首先沒有找到完全匹配的函數,因此對函數模板進行實例化,它應該調用函數模板的實例化版本:char max(char,char)。

調用max(i,c)時,首先,查找完全匹配的版本,它與char max(int,char)完全匹配,因此就調用這個重載函數版本。

調用max(c,i)時,既找不到完全匹配的函數版本,又找不到能與之匹配的模板函數,所以只好試第三步,看對參數類型轉換后能否有匹配的,將max(c,i)中的c轉換成int型后與int max(int,int)匹配,因此就執行這個重載函數版本。

調用max(f,f)時,找不到與它完全匹配的函數,那么,函數模板實例化后的版本中的模板函數float max(float,float)可與它匹配,因此它就調用模板函數。

調用max(f,i)時,既找不到完全匹配的函數,又找不到合適的模板函數,只好對其參數進行類型轉換,其中f轉換為int類型后,與int max(int,int)相匹配,因此就調用這個重載函數版本。

在主函數main()中,調用max(pa,pb)函數,由于兩個參數均為用戶自定義point類類型,找不到與它完全匹配的函數,那么,函數模板實例化后的版本中的模板函數point max(point,point)可與它匹配,因此它就調用模板函數。

在point類類型定義中,定義兩點分別到原點(0,0)的距離,作為兩點比較大小的依據,如某點離原點越遠,則認為該點越大。point類的成員函數point_sqrt()求點到原點的距離,友員函數int operator>(point px,point py)用來重載”>”運算符,判斷point類對象的大小。

3 需要注意的問題

其一,利用模板函數的函數體重載定義非模板函數時,只需聲明,不用給出函數體,且聲明時必須注意各模板參數的實參類型必須一致。如:int max(int,int)等。

其二,重新定義重載函數體時,特別要注意避免產生預期的和非預期的二義性。例如,若對函數模板有這樣兩個重載函數:

int max(int,int); //重載聲明

char max(int x,char y) //重新定義

{ …}

當進行函數調用時有這樣一個調用形式:max(i,f);

此處i為int類型,f為float類型,系統無法決定該調用與這兩個重載函數中的哪一個相聯系,既可以將f轉換成int類型后調用max(int,int),又可以將f轉換成char類型后調用max(int,char)。這個函數調用就存在著二義性。

4 結語

該文討論了利用重載函數模板的方法實現模板參數類型的顯式轉換機制,并說明了在實際應用中必須注意的問題。事實上,在實際編程中,情況可能更復雜些,如用戶自定義結構類型、聯合類型、類類型參數的轉換等,均需視具體情況給出適當的輔助函數以實現模板參數類型的轉換。

參考文獻

[1] 王燕.面向對像的理論與C++實踐[M].北京:清華大學出版社,2002.

[2] 錢能.C++程序設計教程[M].北京:清華大學出版社,2009.

[3] 鄭阿奇.Visual c++教程[M].北京:機械工業出版社,2008.

[4] [美]H.M.Deitel,P.J.Deitel著,C++大學教程[M].2版.邱仲潘,譯.北京:電子工業出版社,2003.

主站蜘蛛池模板: 亚洲视频在线观看免费视频| 久久综合结合久久狠狠狠97色| 波多野结衣一区二区三区AV| 国产精品欧美激情| 欧美性色综合网| 亚洲成年人片| 色男人的天堂久久综合| 国产激情无码一区二区APP| 视频一本大道香蕉久在线播放| 日韩美一区二区| 欧美精品v日韩精品v国产精品| 91精品福利自产拍在线观看| 成人韩免费网站| 91精品福利自产拍在线观看| 精品人妻一区二区三区蜜桃AⅤ| 免费一级全黄少妇性色生活片| 日韩精品一区二区深田咏美| 欧美成人aⅴ| 天堂亚洲网| 性视频一区| 国产v精品成人免费视频71pao| 美女视频黄又黄又免费高清| 成年av福利永久免费观看| 国产精品福利在线观看无码卡| 91www在线观看| 99尹人香蕉国产免费天天拍| 美女一区二区在线观看| 日韩高清无码免费| 亚洲伦理一区二区| 日韩激情成人| 婷婷伊人五月| 中文成人在线视频| 中文字幕亚洲精品2页| 欧美国产日产一区二区| 区国产精品搜索视频| 一级毛片免费播放视频| 国产网站免费| 国产亚洲视频中文字幕视频| 亚洲综合香蕉| 亚洲色图欧美激情| 中文字幕在线看视频一区二区三区| 亚洲综合二区| 日本免费高清一区| 亚洲丝袜第一页| 波多野吉衣一区二区三区av| 欧美激情成人网| 午夜性爽视频男人的天堂| 在线观看亚洲精品福利片 | 成人亚洲国产| 一级做a爰片久久毛片毛片| 麻豆AV网站免费进入| 日韩在线网址| 亚洲综合精品香蕉久久网| 亚洲视频免| 无码专区在线观看| 好久久免费视频高清| 国产午夜无码片在线观看网站| 亚洲精品免费网站| 色综合中文字幕| 国产理论最新国产精品视频| 国产亚洲一区二区三区在线| 欧美成人区| 中国精品自拍| 欲色天天综合网| 亚洲婷婷六月| 日本尹人综合香蕉在线观看 | 国产欧美高清| 日韩中文精品亚洲第三区| 国产美女一级毛片| 99热国产这里只有精品9九| 最新日本中文字幕| 精品1区2区3区| 又污又黄又无遮挡网站| 婷婷六月在线| 色噜噜在线观看| 亚洲男人天堂网址| 日韩欧美高清视频| 日韩av手机在线| 午夜丁香婷婷| 国产91丝袜在线播放动漫 | 免费毛片视频| 国产主播在线观看|