编写与类型无关的逻辑代码,是代码复用的一种手段。模板是泛型编程的基础
代表一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本(它本身不是类或函数)
产生模板特定类型的过程称为函数模板的实例化
template <typename T>
T Add(T left,T right)
{
return left + right;
}
int main()
{
Add(1,2);
Add(1.0,2.0);
Add('1','1');
Add(1,1.0);//error:模板参数“T”不明确
//模板函数不会进行类型转换
Add<int>(1, '1');//显式实例化
Add<double>(1, 1.0);
Add(1,(int) 1.0);//隐式实例化
return 0;
}
从函数实参确定模板形参类型和值得过程称为模板实参推断
一般不会转换实参已匹配以有的实例化,相反会产生新的实例;
编译器只会执行两种转换:1.const转换;2.数组或函数到指针的转换
const转换
接收const引用或const指针的函数可以分别用非const对象的引用或者指针来调用
数组或函数到指针的转换
如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换。数组实参将当做指向其第一个元素的指针,函数实参当做指向函数类型的指针
typedef double T;
//模板形参的名字在同一模板中只能使用一次
template <typename T, typename T>// error C2991: 重定义 模板 参数“T”
//所有模板形参前必须加上class/typename关键字修饰
template <typename T,U>//error C2061: 语法错误: 标识符“U”
template <typename T = int> //可以指定缺省的模板实参
T Add(T left=1, T right=2 )//缺省的调用参数
{
cout << "T type = " << typeid(T).name() << endl;//打印模板参数T的类型
return left + right;
}
T val;//全局变量
int main()
{
Add();
cout << "T type = " << typeid(T).name() << endl;//打印全局变量的类型
return 0;
}
模板形参的名字只能在模板形参之后到模板声明或定义的末尾使用
模板内部定义的常量
template <typename T = int ,int N = 10> //N:非模板类型参数
void Funtest(T(&_array)[N]) //数组引用
{
for (int i = 0; i < N; ++i)
{
_array[i] = 0;
}
}
int main()
{
const int c = 3;
int a[4];
int b[c + 1];
Funtest(a);
Funtest(b);
return 0;
}
int Max(const int& a, const int& b) //同名的非模板函数和模板函数可以同时存在
{
return a > b ? a : b;
}
template <typename T>
T Max(const T& a,const T& b)
{
return a > b ? a : b;
}
template <typename T1, typename T2>
T1 Max(const T1& a, const T2& b)
{
return a > b ? a : b;
}
int main()
{
Max(1, 2);//优先调用非模板函数
Max<>(1, 2);//显示指定,只能调用模板
Max(1, 2.0);//优先调用优化模板template
return 0;
}
template <typename T>//模板实例
int compare(T a, T b)//比较了地址
{
if (a < b)
return -1;
if (a>b)
return 1;
return 0;
}
template <>//模板特化 在模板实例之后
//特化的声明必须与特定的模板相匹配
//int compare(char* p1, char* p2)//error :不是函数模板的专用化
int compare<const char*>(const char* p1, const char* p2)
{
return strcmp(p1,p1);
}
int main()
{
char* p1 = "abcd";
char* p2 = "abce";
const char* p3 = "abcd";
const char* p4 = "abce";
cout << compare(p1, p2) << endl;
cout << compare(p3, p4) << endl;
return 0;
}
template <typename T>
T Max(const T& a, const T& b)
{
return a > b ? a : b;
}
template <typename T>
T Max(const T& a, const T& b, const T& c)//重载
{
return Max(Max(a, b), c);
}
int main()
{
Max(1, 2);
Max(1, 2, 4);
return 0;
}