- 1. 函数模板
- 1.1 函数模板特点
- 1.2 代码示例
- 1.2.1 例1:类型推演
- 1.2.2 例2:类型推演失败
- 1.2.3 例3:类型推演
- 2. 模板函数
- 2.1 定义
- 2.2 泛化
- 2.3 模板类型推演示例
- 2.3.1 类型推演示例
- 2.3.2 推演失败案例,类型不匹配
- 2.3.3 无类型指针示例
- 2.4.模板函数的引用
- 2.5 引用与指针结合
- 2.6 引用与二级指针结合
- 2.7 模板函数类型推演示例
- 2.8 模板函数的重载
- 3. 类模板
- 3.1 概念
- 3.2 代码示例
- 3.3 模板函数类型
- 3.4 模板函数中的new
- 3.5 模板类型识别
- 3.6 综合代码示例
1. 函数模板 1.1 函数模板特点
(1)函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,简化重载函数的设计。函数模板定义如下:template<模板参数表>返回类型函数名(形式参数表) {.....; }//函数体
(2)<模板参数表>(template parameter list)尖括号中不能为空,参数可以有多个,用逗号分开。
模板参数主要是模板类型参数。
(3)模板类型参数(template type parameter)代表一种类型,由关键字class或typename(建议用typename )后加一个标识符构成,在这里两个关键字的意义相同,它们表示后面的参数名代表一个潜在的内置或用户定义的类型。
(4)函数模板根据一组实际类型或(和)值构造出独立的函数的过程通常是隐式发生的,称为模板实参推演(templateargument deduction)。
(5)为了判断用作模板实参的实际类型,编译器需检查函数调用中提供的函数实参的类型。ia 的类型为int数组,dx的类型为double 数组。都被用来决定每个实例的模板参数。该过程称为模板实参推演。
1.2 代码示例 1.2.1 例1:类型推演代码示例
#includeusing namespace std; template void fun(T a) { T x, y; cout << "T type:" << typeid(T).name() << endl; cout << "a type:" << typeid(a).name() << endl; } int main() { //int x = 10;//int int* //const int x=10;//int const int* }
运行结果
因为明确给出需要指针类型,给出的是整型,类型不匹配,推演失败,函数都可以重载
using namespace std; template1.2.3 例3:类型推演void fun(T* a)//必须是指针所有推演失败 部分泛化 { T x, y; cout << "T type: " << typeid(T).name() << endl; cout << "a type: " << typeid(a).name() << endl; } int main() { int x = 10; const int y = 10; fun(x); fun(y); //推演失败解决办法:加引用 fun(&x);//int int* fun(&y);//int const int* return 0; }
template2. 模板函数 2.1 定义void fun(T& a) { T x, y; cout << "T type: " << typeid(T).name() << endl; cout << "a type: " << typeid(a).name() << endl; } int main() { int x = 10; const int y = 10; int* xp = &x; const int* yp = &y; fun(x); fun(y); fun(&x); fun(&y); fun(xp); fun(yp); return 0; }
在编译main()函数中,由编译函数模板(functron template)而生成的函数,称为模板函数(template function).这两个概念须分清楚。
2.2 泛化void fun(T a)//完全泛型 void fun(T *a);//部分泛型 void fun2.3 模板类型推演示例 2.3.1 类型推演示例(const char* a)//完全特化
template2.3.2 推演失败案例,类型不匹配void fun(T a) { T x, y; cout << "T type: " << typeid(T).name() << endl; cout << "a type: " << typeid(a).name() << endl; } int main() { int x = 10; const int y = 20; int* xp = &x; const int* yp = &y; fun(x);//int int fun(y);//int int fun(&x);//int* int* fun(&y);//const int* const int* fun(xp);//int* int* fun(yp);//const int* const int* fun(&xp);//int** int** fun(&yp);//const int** const int** }
template2.3.3 无类型指针示例void fun(T* a) { T x, y; cout << typeid(T).name() << endl; cout << typeid(a).name() << endl; } int main() { int x = 10; const int y = 20; fun(x);//推演失败(类型不匹配) fun(y);//推演失败 return 0; }
代码示例
templatevoid fun(T* a) { T x, y; cout << typeid(T).name() << endl; cout << typeid(a).name() << endl; } int main() { int x = 10; const int y = 20; int* xp = &x; const int* yp = &y; void* p = &x;//无类型指针 //带有类型萃取能力 fun(&x);//int int* fun(&y);//const int const int* fun(p);//void void* return 0; }
无类型无法定义变量
2.4.模板函数的引用代码示例
templatevoid fun(T& a)//引用是和变量名结合,不是和类型名结合 { T x = 0, y = 0;//进行初始化才能编译通过 cout << typeid(T).name() << endl; cout << typeid(a).name() << endl; } int main() { int x = 10; const int y = 20; fun(x);//int int& fun(y);//const int const int& return 0; }
运行结果
代码示例
templatevoid fun(T& a)//引用是和变量名结合,不是和类型名结合 { T x = 0, y = 0;//进行初始化才能编译通过 cout << typeid(T).name() << endl; cout << typeid(a).name() << endl; } int main() { int x = 10; const int y = 20; int* xp = &x; const int* yp = &y; fun(xp);//int* int*& fun(yp);//const int* const int*& return 0; }
运行结果
template2.7 模板函数类型推演示例void fun(T const& a)//引用是和变量名结合,不是和类型名结合 { T x = 0, y = 0;//进行初始化才能编译通过 cout << typeid(T).name() << endl; cout << typeid(a).name() << endl; } int main() { int x = 10; const int y = 20; fun(&x);//int* int const* fun(&y);//int* int const* return 0; }
代码示例
templatevoid fun(T a) { cout << "T a" << endl; } template void fun(T* a) { cout << "T *a" << endl; } template void fun(const T* a) { cout << "const T*" << endl; } int main() { int x = 10; const int y = 20; fun(x);//T fun(&x);//T* fun(&y);//const T* }
运行结果
2.8 模板函数的重载template3. 类模板 3.1 概念void fun(T a, int) { } template void fun(T a, char) { } int main() { fun(12, 23); fun(12, 'a'); return 0; }
(1)类模板不存在推演过程
(2)类模板中的函数都是模板函数
代码示例
void push(const T& x)
{
cout<
3.2 代码示例
//类模板
template
class stack
{
T* data;
size_t count;
public:
void Push(const T& x);
};
3.3 模板函数类型
template
class Stack
{
T data[N];
public:
void push(const T& x);
};
int main()
{
//is和ist类型不相同
Stack is;
Stack ist;
return 0;
}
3.4 模板函数中的new
template
class Array
{
enum { INIT = 10 };
T* data;//.heap 10
size_t capacity;//10
size_t count;//5
public:
Array()
{
count = 0;
data = new T[capacity = INIT];//连续开辟数组,调动构造函数,对每个空间构造函数
}
~Array() { delete[]data; }
};
int main()
{
Array ar;
Array dr;
}
3.5 模板类型识别
int main()
{
Array a;//不是模板类型,已经被实例化
Array b;
}
3.6 综合代码示例
#define _CRT_SECURE_NO_WARNINGS
#include"stdio.h"
#include
#include
#include
#include
#include
#include



