官术网_书友最值得收藏!

2.1 函數模板

2.1.1 基本范例

創建一個函數,能將兩個int類型的形參相減,將結果值返回,代碼如下。

如果是兩個float類型的形參相減呢?那么還要再寫一個函數版本,代碼如下。

可以看到,上面是兩個同名函數,屬于函數重載。

這兩個函數的區別是什么呢?除了參數類型,函數體的代碼是一樣的,重復寫這種代碼完全沒有必要,如果將來參數類型再發生改變,還得再寫一個類似的函數。那么,這種場合就是使用函數模板的最好場合。

這里,不想為每種類型都定義一個不同的函數,所以采取定義一個通用的函數模板的策略。下面看一看怎樣利用模板寫出一個適合多種參數類型求差值的函數,將剛才的兩個重載函數全部注釋,增加以下代碼,定義一個函數模板。

     template <typename T>
     T Sub(T tv1, T tv2)
     {
        return tv1 - tv2;
     }

在main()主函數中添加代碼:

     int subv = Sub(3, 5);
     cout << "subv = " << subv << endl;
     double subv2 = Sub(4.7 , 2.1);
     cout << "subv2 = " << subv2 << endl;

運行程序,查看結果:

     subv = -2
     subv2 = 2.6

上述就是一個函數模板的典型范例,因為函數參數的類型沒有確定,所以用T表示,這個T可以稱為模板參數,更確切地,是一個類型模板參數,因為它代表的是一個類型

這里有一些模板的基礎知識:①模板的定義是以template關鍵字開頭;②類型模板參數T前面用typename修飾(語法就這樣規定),所以,遇到typename就應該知道其后跟的是一個類型;同時,這里的typename可以用class取代(但推薦使用typename),但這里的class并沒有“類”的意思(有些人習慣于使用typename表明對應的模板實參可以是任意類型,而使用class表明對應的模板實參必須是一個類類型);③類型模板參數T(代表一個類型)以及前面的修飾符typename都是用尖括號< >括起來的;④T可以換成任何其他標識符,對程序沒有影響,用T是一種使用習慣而已。

如果讀者對這些最基礎的模板知識仍感到陌生,從現在開始逐步去掌握,它們其實都很簡單。

如果繼續在main()主函數中添加代碼:

     string a("abc"), b("def");
     string addresult = Sub(a, b);

編譯一下,發現報錯,這是為什么呢?因為這里的T是string,而string類型是不支持減法操作的,所以Sub()這個函數模板里面的代碼行就是不合法的。這說明Sub()函數模板要想成功編譯,傳入的類型T必須要支持減法操作。所以,同樣一個函數模板,可能以某種方式進行調用是合法的,而換一種方式調用就不合法了。尤其值得注意的是,這種合法性,在編譯階段就可以由編譯器判斷出來,因為這些對Sub()函數模板的調用代碼就在這里擺著,編譯器有能力在編譯時就從這些調用代碼中去推斷Sub()函數模板中的模板參數T的類型。根據模板參數T的類型,編譯器就能夠判斷出這個類型是否支持減法運算。

主站蜘蛛池模板: 科技| 龙岩市| 栾城县| 曲松县| 甘南县| 扶绥县| 舟曲县| 卢龙县| 漳州市| 电白县| 龙胜| 行唐县| 晋中市| 鸡东县| 衢州市| 郸城县| 应用必备| 蒙城县| 含山县| 大关县| 托克逊县| 景德镇市| 岑溪市| 南安市| 田林县| 文昌市| 澎湖县| 仁怀市| 广昌县| 桐梓县| 盐池县| 伽师县| 台南市| 新晃| 华池县| 永州市| 无为县| 石河子市| 从江县| 盱眙县| 宣城市|