C++函數模板宣告和實現

2020-07-16 10:04:43
過載函數使程式設計變得方便,因為對於執行類似操作的一組函數,只要記住一個函數名稱即可。但是,每個函數都必須單獨編寫。例如,來看以下過載的 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 通過函數模板生成的兩個函數範例