C++模板-32-普通函數和模板函數調用規則

上一篇學習了普通函數和模板函數的區別,這一篇繼續學習兩者的調用規則。也就是在同一個文件中,如果同時存在普通函數名稱和模板函數名稱一致,那麼兩者之間的調用規則是如何。

 

1.如果普通函數和模板函數都可以調用,優先調用普通函數。

下面代碼,普通函數和模板函數名稱一樣,傳入參數也一致,運行代碼是調用模板函數還是普通函數

#include <iostream>
using namespace std;

//模板函數
template <class T>
void myAdd(T a, T b)
{
    cout << "調用模板函數" << endl;
}

//普通函數
void myAdd(int a, int b)
{
    cout << "調用普通函數" << endl;
}

void test01()
{
    myAdd(10, 9);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

編譯運行

說明,如果普通函數和模板函數都可以調用,默認優先調用普通函數。

 

2.可以通過空模板參數列表,強制調用模板函數

如果上面的情況,我們不想默認使用普通函數,那麼就需要使用空模板函數,強制顯示調用模板函數

#include <iostream>
using namespace std;

//模板函數
template <class T>
void myAdd(T a, T b)
{
    cout << "調用模板函數" << endl;
}

//普通函數
void myAdd(int a, int b)
{
    cout << "調用普通函數" << endl;
}

void test01()
{
    myAdd<>(10, 9);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

上面第19行使用了<>,也就是空模板參數列表。 編譯運行

 

3.函數模板也可以發生函數重載

我們前面學習過普通函數的重載,函數模板也可以發生重載。

#include <iostream>
using namespace std;

//模板函數
template <class T>
void myAdd(T a, T b)
{
    cout << "調用模板函數1" << endl;
}

template <class T>
void myAdd(T a, T b, T c)
{
    cout << "調用模板函數2" << endl;
}

//普通函數
void myAdd(int a, int b)
{
    cout << "調用普通函數" << endl;
}

void test01()
{
    myAdd<>(10, 9);
    myAdd<>(10, 9, 1);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

上面模板函數發生重載,參數個數不一樣。

 

4.如果函數模板可以產生更好匹配,優先調用函數模板

有時候編譯器認爲調用普通函數和模板函數都可以,只不過普通函數可以需要隱式轉換,而模板函數如果推導出來類型,也是可以調用。這種情況下,編譯器覺得模板更好匹配,隱式轉換太麻煩,所以會優先調用函數模板

#include <iostream>
using namespace std;

//模板函數
template <class T>
void myAdd(T a, T b)
{
    cout << "調用模板函數" << endl;
}

//普通函數
void myAdd(int a, int b)
{
    cout << "調用普通函數" << endl;
}

void test01()
{
    char a = 'a';
    char b = 'b';
    myAdd(a, b);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

前面學習過 char在一定範圍內是可以隱式轉換爲int類型,所以在test01()中,編譯器認爲兩個函數都可以調用,但是模板匹配更好,所以這裏有點調用了模板函數。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章