1.什么是函式模版
??函式模板,實際上是建立一個通用函式,其函式型別和形參型別不具體制定,用一個虛擬的型別來代表,這個通用函式就成為函式模板
2.怎么撰寫函式模版
//T代表泛型的資料型別,不是只能寫T,
template<class T>//讓編譯器看到這句話后面緊跟著的函式里有T不要報錯
void mySwap(T &a,T &b)
{
T tmp = a;
a = b;
b = tmp;
}
//可以這樣定義函式模版
template<typename T>
void func2(T a,T b)
{
}
3.怎么使用函式模版
//T代表泛型的資料型別,不是只能寫T,
template<class T>//讓編譯器看到這句話后面緊跟著的函式里有T不要報錯
void mySwap(T &a,T &b)
{
T tmp = a;
a = b;
b = tmp;
}
template<class T>
void mySwap2()
{
}
//使用函式模版
void test02()
{
int a = 10;
int b = 20;
//1.編譯器會根據實參來自動推導資料型別
mySwap(a,b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
char c = 'c';
//mySwap(a, c);err,資料型別要一致
//2.顯示的指定型別
mySwap<int>(a, b);//<>用引數串列告訴編譯器我只傳int類
//mySwap<double>(a, b);//注意:指定型別,傳入時不能不一致
mySwap<>(a,b);
//mySwap2<>();//err 呼叫時,必須讓編譯器知道泛型T具體是什么型別
}
4.編譯器會對函式模版和類模版進行二次編譯
//T代表泛型的資料型別,不是只能寫T,
template<class T>//讓編譯器看到這句話后面緊跟著的函式里有T不要報錯
void mySwap(T &a,T &b)//第一次編譯
{
T tmp = a;
a= b;
b = tmp;
}
//使用函式模版
void test02()
{
int a = 10;
int b = 20;
//1.編譯器會根據實參來自動推導資料型別
mySwap(a,b);//編譯器在函式模版被呼叫時,進行第二次編譯
/*
void mySwap(int &a,int &b)
{
int tmp = a;
a= b;
b = tmp;
}
*/
cout << "a=" << a << endl;
cout << "b=" << b << endl;
}
5.隱式轉換
template<class T>
T func(T a, T b)
{
return a + b;
}
void test03()
{
int a = 10;
double b = 20.2;
//如果使用引數串列指定資料型別,那么實參中可以隱式轉換
//如果轉換成功,就呼叫,轉換不成功就報錯
cout << func<int>(10,20.2) << endl;
}
6.函式模板和普通函式的區別
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//普通函式
int myPlus(int a, int b)
{
return a + b;
}
template<class T>
int myPlus2(T a, T b)
{
return a + b;
}
void test()
{
int a = 10;
int b = 20;
char c = 'a';
//普通函式可以進行隱式轉換
myPlus(a, c);
//函式模版不能直接的進行隱式轉換
//myPlus2(a, c);
myPlus2<int>(a, c);//如果要進行隱性轉換,必須加上引數串列
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
7.普通函式和函式模版的呼叫規則
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//普通函式
void myPlus(int a, int b)
{
cout << "普通函式" << endl;
}
template<class T>
void myPlus(T a, T b)
{
cout << "函式模版" << endl;
}
template<class T>
void myPlus(T a, T b, T c)
{
cout << "函式模版 T c" << endl;
}
//1.函式模版和普通函式可以多載
void test()
{
int a = 10;
int b = 20;
//2.如果普通函式和函式模版都可以實作的功能,普通函式優先呼叫
myPlus(a, b);
//3.可以使用<>空引數串列強制呼叫函式模版
myPlus<>(a, b);
//4.函式模版之間也可以進行多載
//5.如果函式模版可以產生更好的匹配,那么優先使用函式模版
char c1 = 'a';
char c2 = 'b';
myPlus(c1, c2);
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
8.函式模版的局限性和解決方法
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<string>
template<class T>
void func(T a, T b)
{
if (a > b)
{
cout << "a>b" << endl;
}
else
{
cout << "a<=b" << endl;
}
}
void test()
{
int arr[20];
int arr2[10];
func(arr, arr2);
}
class Maker
{
public:
Maker(string name,int age)
{
this->age = age;
this->name = name;
}
public:
string name;
int age;
};
template<class T>
void myfunc(T &a, T &b)
{
if (a > b)
{
cout << "a>b" << endl;
}
else
{
cout << "a<=b" << endl;
}
}
//不建議具體化函式模版,因為沒有通用性
//具體化函式模版,注意上面的函式模版要有,才能具體化
template<>void myfunc<Maker>(Maker &a, Maker &b)
{
cout << "函式模版的具體化" << endl;
if (a.age > b.age)
{
cout << "a>b" << endl;
}
else
{
cout << "a<=b" << endl;
}
}
void test02()
{
Maker m1("aaa", 10);
Maker m2("bbb", 20);
myfunc(m1, m2);
}
int main()
{
test02();
system("pause");
return EXIT_SUCCESS;
}
參考資料
參考資料來源于黑馬程式員
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/543519.html
標籤:其他
上一篇:Stream流
