C語言中文網 目錄
首頁 > 編程筆記 > C++筆記 閱讀:920

C++函數模板聲明和實現

重載函數使編程變得方便,因為對于執行類似操作的一組函數,只要記住一個函數名稱即可。但是,每個函數都必須單獨編寫。例如,來看以下重載的 square 求平方函數:
int square(int number)
{
    return number * number;
}
double square(double number)
{
    return number * number;
}
這兩個函數之間的唯一區別是它們的返回值及其形參的數據類型。在這種情況下,編寫函數模板比重載函數更方便。函數模板允許程序員編寫一個單獨的函數定義,以處理許多不同的數據類型,而不必為每個使用的數據類型編寫單獨的函數。

函數模板不是實際的函數,而是編譯器用于生成一個或多個函數的 "模具"。在編寫函數模板時,不必為形參、返回值或局部變量指定實際類型,而是使用類型形參來指定通用數據類型。當編譯器遇到對函數的調用時,它將檢查其實參的數據類型,并生成將與這些數據類型配合使用的函數代碼。

以下是一個 square 函數的函數模板:
template<class T>
T square(T number)
{
    return number * number;
}
函數模板由一個模板前綴標記開始,該模板前綴以關鍵字 template 開始,接下來是一組尖括號,里面包含一個或多個在模板中使用的通用數據類型。通用數據類型以關鍵字 dass 開頭,后面跟著代表數據類型的形參名稱。

在上面的 square 函數模板示例中,只使用了一個名為 T 的形參(如果有更多的話,它們將用逗號分隔)。在此之后,除了使用類型形參代替實際的數據類型名稱之外,其他的都可以像往常一樣寫入函數的定義。在本函數模板示例中,以下是其函數頭:

T square(T number)

其中,T 是類型形參或通用數據類型。該函數頭定義了一個 square 函數,它返回一個 T 類型的值,并使用了一個形參 number,這也是 T 類型的數字。

如前所述,編譯器會檢查對 square 的每次調用,并以適當的數據類型填充 T,例如,以下調用將使用 int 參數:

int y, x = 4;
y = square(x);

以上代碼將導致編譯器生成以下函數:
int square(int number)
{
    return number * number;
}
但是,如果使用以下語句調用 square 函數:

double y, d = 6.2;
y = square(d);

那么編譯器生成的函數將如下所示:
double square(double number)
{
    return number * number;
}
下面的程序演示了該函數模式的用法:
// This program uses a function template.
#include <iostream>
#include <iomanip>
using namespace std;

// Template definition for square function
template <class T>
T square(T number)
{
    return number * number;
}

int main()
{
    cout << setprecision(5);
    //Get an integer and compute its square
    cout << "Enter an integer: ";
    int iValue;
    cin >> iValue;
    // The compiler creates int square(int) at the first occurrence of a call to square with an int argument
    cout << "The square is " << square(iValue);
    // Get a double and compute its square
    cout << "\nEnter a double: ";
    double dValue;
    cin >> dValue;
   
    // The compiler creates double square(double)at the first
    // occurrence of a call to square with a double argument
    cout << "The square is " << square (dValue) << endl;
    return 0;
}
程序輸出結果:

Enter an integer: 3
The square is 9
Enter a double: 8.3
The square is 68.89

注意,函數模板中定義的所有類型形參必須在函數的形參列表中至少出現一次。


圖 1 通過函數模板生成的兩個函數實例

由于編譯器在上面的程序中遇到了對 square 函數的兩次調用,并且每次都使用了不同的形參類型,所以它生成了兩個函數實例的代碼(如圖 1 所示):
  • 一個帶有 int 形參和 int 返回類型的函數實例;
  • 一個帶有 double 形參和 double 返回類型的函數實例;

請注意,在上邊的程序中,模板出現在所有對 square 函數的調用之前。與常規函數一樣,當編譯器遇到對模板函數的調用時,必須已經知道模板的內容。因此,模板應放在程序的頂部附近或頭文件中。

注意,函數模板僅僅是函數的規范,本身并不會導致使用內存。當編譯器遇到對模板函數的調用時,才會在內存中創建該函數的實際實例。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo