在定義模板類型參數時,typename和class作用相同!
1. 函數模板
在編譯階段執行 a 定義點 模板頭部 b 調用點 模板函數
2. 模板函數
3. 模板的實例化 // 函數模板到模板函數的一個轉換過程
4.模板的實例推演
int main()
{
Sum(10,20); //模板的實參推演
//程序可以運行,系統會自動判斷10和20的數據類型,進行推演
return 0;
}
template <typename T,typename E>
T Sum <T a,E b>;
//當Sum內實參數據類型不同時
注意事項: a 不能產生二義性; b 有實參才能推演
5. 模板的特例化(專用化):模板類型不能滿足特殊類型的需求
#include<iostream>
template <typename T>
bool Compare(T a,T b)
{
return a>b; //代碼錯誤,只比較地址,不比較地址內值
}
/*
bool Compare<char *>("Hello","World")
{
return a>b;
}
*/
int main()
{
Compare<char *>("Hello","World");
return 0;
}
#include<iostream>
template<typename T>
bool Compare(T a, T b)
{
std::cout << "template<typename T> bool Compare(T,T)" << std::endl;
return a > b;
}
template <> //特例化[已經全特化,爲空]
bool Compare<char *>(char *a,char *b)
{
return strcmp(a,b)>0;
}
int main()
{
Compare<char *>("Hello","World");
return 0;
}
特例化應該符合模板的實例化邏輯:
a 完全特例化[函數模板] 全特化 [具體到某一個類型]
b 部分特例化[類模板] 偏特化 [具體到一部分類型]
特例化的調用優先級 > 模板實例化 [所以特例化直接調用]
6. 模板的類型參數
7. 模板的非類型參數
特點: a 模板的非類型參數是常量
b 模板的非類型參數不能是float、double類型
template<typename T, int LEN>
//int LEN 就是非類型參數
8. 模板的默認值
#include <iostream>
template<typename A = int, typename B, typename C = double>
C Add(A a, B b)
{
//C c = C(); //初始化
std::cout << "A : " << typeid(A).name() << std::endl; //double
std::cout << "B : " << typeid(B).name() << std::endl; //int
std::cout << "C : " << typeid(C).name() << std::endl; //double
return a + b;
}
int main()
{
auto rt = Add(10.1, 20);
std::cout << "rt : " << typeid(rt).name() << std::endl;
return 0;
}
函數模板的默認值,不是C++98標準,是C++11 【如果有實參推演,則不使用默認值,反之則使用】
類模板的默認值,是C++98標準 【不遵循自右向左依次賦予的規則】
9. 模板接收不明確類型的返回值
auto 自適應的調節類型
auto rt = Add(10.1, 20);
10. 模板的重載
a 普通函數版本
b 模板版本
c 模板特例化版本
優先級:1 > 3 > 2 ps : 要求精確匹配!
11. 模板的顯式實例化
//test.cpp
template<typename T>
T Sum(T a, T b)
{
return a + b;
}
//int a = Sum<int>(10, 20);
template int Sum<int>(int, int);
//main.cpp
template<typename T>
T Sum(T, T);
int main()
{
Sum<int>(10, 10);
Sum<double>(10.2, 10.1);
return 0;
}
template int Sum<int>(int,int) //顯示實例化
模板一般在.h文件中實現
【用模板完成冒泡排序!】
#include <iostream>
template<typename T, int LEN>
void Sort1(T arr[])
{
//LEN = 10;
T tmp = T();
for (int i = 0; i < LEN - 1; i++)
{
for (int j = 0; j < LEN - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
template<typename T>
void Sort(T arr[], int len)
{
T tmp = T();
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
template<typename T>
void Show(T arr[], int len)
{
for (int i = 0; i < len; i++)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
int main()
{
int arr[] = { 21, 32, 43, 234, 23, 42, 4212, 3 };
int len = sizeof(arr) / sizeof(arr[0]);
Show(arr, len);
Sort(arr, len);
Show(arr, len);
//Sort1<int, sizeof(arr) / sizeof(arr[0])>(arr);
Sort1<int, len>(arr);
const int a = 10;
int b = 20;
const int c = b;
c = 10;
return 0;
}