C++编程语言关于模板的学习笔记
1.模板函数
1.1基本概念
模板是在编译时期产生代码,它的执行并不是宏的替换,而是重命名规则
//传参后,模板函数编译时候如下,而不是将Type替换为int
typedef int Type;
void Swap<int>(Type& a,Type& b)
{
Type tmp=a;
a=b;
b=tmp;
}
而下面的N是一个宏替换,替换一个常量,
1.2模板函数推演示例:
通过下面的示例中传入的不同参数,我们来分析一下在编译时期T被推演为什么?(注释已经给出推演的结果)
示例1:
示例2:
示例3:
示例4:
1.3区分完全泛化、部分特化以及完全特化
1.4注意点:
①因为引用(&)的底层是int * const (常性指针),传引用进去之后,编译器对于int* 之后的const无法进行推演,所以编译不通过。
所以我们需要在模板函数中T的后面手动加上const
②模板函数也是可以重载的
2.模板类
2.1模板类编译时的推演规则
给类名称后面加上T的具体类型
然后在类内用typedef给这个具体类型重命名为T
2.2可以有非类型,并且当我们的N为不同的值的时候,对象类型也会不同
比如下面的N分别为100,10,在进行替换之后,会实例化出两个不同的对性(原因是成员属性都不相同,因此就是不同的对象)。
2.3类模板中函数的编译问题
类模板中的函数,如果调动了,类模板里面的函数才会参与编译,不调动就不会参与编译
所以下面将N的值改变,如果我们不调用是并不会检测出错误的。
2.4模板类型参数可以赋默认值
2.5模板类型参数可以有多个
2.6什么时候是模板类型
Arrayiat,因为已经明确的给出一个整型,所以编译器就会实例化出具体的内容,那么这就是一个具体的类型
Array 这就是一个模板类型,因为没有给出明确的类型,编译器无法做出判断要处理怎样的类型。
template<class T>
class Array
{
enum{INIT=10};
T* data;
size_t capacity;
size_t count;
};
int main()
{
Array<int>iar;//这不是一个模板类型,因为编译器会把它实例化为下面的代码:
/*
class Array<int>
{
typedef int T;
enum{INIT=10};
T* data;
size_t capacity;
size_t count;
};
*/
Array//这是一个模板类型
}
2.7类型萃取问题引入
T是一个类型,
seq是一个类型,此类型能够接收的必须是一个模板类型,此模板类型必须带有一个模板参数
如果说在主函数的使用中,出现这样的情况:
Container<int,Array>contatiner;
那么这就会导致Array这不是一个模板类型,变成具体的设计类型,所以应该变成这样:Container<int,Array>contatiner;
如何类型萃取,能够将T明确出来是int类型呢?
不要直接把程序中的T全部换成int,或者其他具体的类型,这是枯燥的,因此需要类型萃取。