#include<iostream>
using namespace std;
//交換兩個整型函數
void swapInt(int& a, int& b) {
?? ?int temp = a;
?? ?a = b;
?? ?b = temp;
}
//交換兩個浮點型函數
void swapDouble(double& a, double& b) {
?? ?double temp = a;
?? ?a = b;
?? ?b = temp;
}
//函數模板
//聲明一個模板,告訴編譯器后面代碼中緊跟著的T不要報錯,T是一個通用數據類型
template<typename T>
void mySwap(T& a, T& b)
{
?? ?T temp = a;
?? ?a = b;
?? ?b = temp;
}
void test01()
{
?? ?int a = 10;
?? ?int b = 20;
?? ?//swapInt(a, b);
?? ?//利用函數模板交換
?? ?//兩種方式
?? ?//1.自動類型推導
?? ?//mySwap(a, b);
?? ?//2、顯示指定類型
?? ?mySwap<int>(a, b);
?? ?cout << "a = " << a << endl;
?? ?cout << "b = " << b << endl;
?? ?//double c = 1.1;
?? ?//double d = 2.2;
?? ?//swapDouble(c,d);
?? ?//cout << "c = " << c << endl;
?? ?//cout << "d = " << d << endl;
}
int main()
{
?? ?test01();
?? ?system("pause");
?? ?return 0;
}
#include<iostream>
using namespace std;
//利用模板提供通用的交換函數
template<class T>//typename可以替換成class
void mySwap(T& a, T& b)
{
?? ?T temp = a;
?? ?a = b;
?? ?b = temp;
}
//函數模板注意事項
// 1、自動類型推導,必須推導出一致的數據類型T,才可以使用
void test01()
{
?? ?int a = 10;
?? ?int b = 20;
?? ?char c = 'c';
?? ?mySwap(a, b); // 正確,可以推導出一致的T
?? ?cout << "a = " << a << endl;
?? ?cout << "b = " << b << endl;
?? ?//mySwap(a, c); // 錯誤,推導不出一致的T類型
}
// 2、模板必須要確定出T的數據類型,才可以使用
template<class T>
void func()
{
?? ?cout << "func 調用" << endl;
}
void test02()
{
?? ?//func(); //錯誤,模板不能獨立使用,必須確定出T的類型
?? ?func<int>(); //利用顯示指定類型的方式,給T一個類型,才可以使用該模板
}
int main() {
?? ?test01();
?? ?test02();
?? ?system("pause");
?? ?return 0;
}
#include<iostream>
using namespace std;
//普通函數與函數模板區別
//1.普通函數調用可以發生隱式類型轉換
//2.函數模板 用自動類型推導,不可以發生隱式類型轉換
//3.函數模板 用顯示指定類型,可以發生隱式類型轉換
//普通函數
int myAdd01(int a, int b)
{
?? ?return a + b;
}
//函數模板
template<class T>
T myAdd02(T a, T b) ?
{
?? ?return a + b;
}
//使用函數模板時,如果用自動類型推導,不會發生自動類型轉換,即隱式類型轉換
void test01()
{
?? ?int a = 10;
?? ?int b = 20;
?? ?char c = 'c';
?? ?cout << myAdd01(a, b) << endl; //正確
?? ?cout << myAdd01(a, c) << endl; //正確,將char類型的'c'隱式轉換為int類型? 'c' 對應 ASCII碼 99
?? ?//自動類型推導
?? ?//cout <<myAdd02(a, c)<< endl; // 報錯,使用自動類型推導時,不會發生隱式類型轉換
?? ?//顯示指定類型
?? ?cout <<myAdd02<int>(a, c)<< endl; //正確,如果用顯示指定類型,可以發生隱式類型轉換
}
int main()
{
?? ?test01();
?? ?system("pause");
?? ?return 0;
}
#include<iostream>
using namespace std;
//普通函數與函數模板調用規則
void myPrint(int a, int b)
{
?? ?cout << "調用的普通函數" << endl;
}
template<typename T>
void myPrint(T a, T b)
{
?? ?cout << "調用的模板" << endl;
}
template<typename T>
void myPrint(T a, T b, T c)
{
?? ?cout << "調用重載的模板" << endl;
}
void test01()
{
?? ?//1、如果函數模板和普通函數都可以實現,優先調用普通函數
?? ?// 注意 如果告訴編譯器? 普通函數是有的,但只是聲明沒有實現,或者不在當前文件內實現,就會報錯找不到
?? ?int a = 10;
?? ?int b = 20;
?? ?myPrint(a, b); //調用普通函數
?? ?//2、可以通過空模板參數列表來強制調用函數模板
?? ?myPrint<>(a, b); //調用函數模板
?? ?//3、函數模板也可以發生重載
?? ?int c = 30;
?? ?myPrint(a, b, c); //調用重載的函數模板
?? ?//4、 如果函數模板可以產生更好的匹配,優先調用函數模板
?? ?char c1 = 'a';
?? ?char c2 = 'b';
?? ?myPrint(c1, c2); //調用函數模板
}
int main()
{
?? ?test01();
?? ?system("pause");
?? ?return 0;
}
#include<iostream>
using namespace std;
#include <string>
//模板局限性
//模板并不是萬能的,有些特定數據類型,需要用具體化方式做特殊實現
class Person
{
public:
?? ?Person(string name, int age)
?? ?{
?? ??? ?this->m_Name = name;
?? ??? ?this->m_Age = age;
?? ?}
?? ?string m_Name;
?? ?int m_Age;
};
//對比兩個數據是否相等函數
//普通函數模板
template<class T>
bool myCompare(T& a, T& b)
{
?? ?if (a == b)
?? ?{
?? ??? ?return true;
?? ?}
?? ?else
?? ?{
?? ??? ?return false;
?? ?}
}
//利用具體化Person的版本實現代碼,具體化優先調用
//具體化,顯示具體化的原型和定意思以template<>開頭,并通過名稱來指出類型
//具體化優先于常規模板
template<> bool myCompare(Person &p1, Person &p2)
{
?? ?if ( p1.m_Name? == p2.m_Name && p1.m_Age == p2.m_Age)
?? ?{
?? ??? ?return true;
?? ?}
?? ?else
?? ?{
?? ??? ?return false;
?? ?}
}
void test01()
{
?? ?int a = 10;
?? ?int b = 20;
?? ?//內置數據類型可以直接使用通用的函數模板
?? ?bool ret = myCompare(a, b);
?? ?if (ret)
?? ?{
?? ??? ?cout << "a == b " << endl;
?? ?}
?? ?else
?? ?{
?? ??? ?cout << "a != b " << endl;
?? ?}
}
void test02()
{
?? ?Person p1("Tom", 10);
?? ?Person p2("Tom", 10);
?? ?//自定義數據類型,不會調用普通的函數模板
?? ?//可以創建具體化的Person數據類型的模板,用于特殊處理這個類型
?? ?bool ret = myCompare(p1, p2);
?? ?if (ret)
?? ?{
?? ??? ?cout << "p1 == p2 " << endl;
?? ?}
?? ?else
?? ?{
?? ??? ?cout << "p1 != p2 " << endl;
?? ?}
}
int main()
{
?? ?test01();
?? ?test02();
?? ?system("pause");
?? ?return 0;
}