在定义模板类型参数时,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;
}