C++函數或函數模板的匹配順序

2020-07-16 10:04:22
函數模板可以過載,只要它們的形參表不同即可。例如,下面兩個模板可以同時存在:
template <class T1, class T2>
void print(Tl arg1, T2 arg2 )
{
    cout << arg1 << " " << arg2 << endl;
}
template <class T>
void print(T arg1, T arg2)
{
    cout << arg1 << " " << arg2 << endl;
}
在有多個函數和函數模板名字相同的情況下,一條函數呼叫語句到底應該被匹配成對哪個函數或哪個模板的呼叫呢? C++ 編譯器遵循以下先後順序:
  1. 先找引數完全匹配的普通函數(非由模板範例化得到的函數)。
  2. 再找引數完全匹配的模板函數。
  3. 再找實參經過自動型別轉換後能夠匹配的普通函數。
  4. 如果上面的都找不到,則報錯。

例如下面的程式:
#include <iostream>
using namespace std;
template <class T>
T Max(T a, T b)
{
    cout << "Template Max 1" << endl;
    return 0;
}
template<class T, class T2>
T Max(T a, T2 b)
{
    cout << "Template Max 2" << endl;
    return 0;
}
double Max(double a, double b) {
    cout << "Function Max" << endl;
    return 0;
}
int main() {
    int i = 4, j = 5;
    Max(1.2, 3.4);  //呼叫 Max 函數
    Max(i, j);  //呼叫第一個Max模板生成的函數
    Max(1.2, 3);  //呼叫第二個Max模板生成的函數
    return 0;
}
程式的輸出結果是:
Function Max
Template Max 1
Template Max 2

如果把程式中的 Max 函數和第二個 Max 模板都去掉,按照上面所說的 4 條匹配規則,第 23 行的Max(1.2, 3);編譯時就會出錯。因為從第一個 Max 模板沒法生成與之型別完全匹配的模板函數 Max(double, int)。雖然從該 Max 模板可以生成 int Max( int, int) 和 double Max( double, doube),但是到底應該把 1.2 自動轉換成 int 型別後呼叫前者,還是應該把 3 自動轉換成 double 型別後呼叫後者呢?這是有二義性的,因此編譯器會報錯。