模板和STL知识点

一、为什么使用模板
1、C/C++是一种静态类型语言(预处理->汇编->编译->链接),速度快,但是实现通用代码麻烦,例如:实现支持所有类型的快速排序
2、借助函数重载实现通用代码,好处是实现简单,但代码段会增加。
3、借助宏函数来实现通用代码,类型检查不严格。
4、借助回调函数实现通用代码,使用麻烦。
5、由于以上原因C++之父在C++中实现了模板技术,让C++能够支持泛型编程。
二、函数模板
1、函数模板定义
template<typename 类型参数1,type 类型参数2…>
返回值 函数名(参数列表)
{
return 返回值;
}
Template
T find(T*arr,size_t len)
{
return val;
}
可以任何标志符作为类型参数名,但使用‘T’是俗成约定的,它表示调用这个函数时所指定的任意类型。
2、函数模板的使用
C++编译的编译器并不是把模板编译成一个可以处理任何类型的单一实体,而根据模板的使用者的参数,产生不同的函数的实体。根据具体类型代表模板参数生成函数实体过程叫实例化。模板在使用时才实例化,可以自动实例化,也可以手动实例化(在函数调用时函数名与小括号加一对<类型参数>)。
每个函数模板都会进行二次编译,第一次在实例化之前检查模板代码本身是否正确,在实例化过程中,结合所使用的类型参数,再次检查模板代码,是否所有的代码都有效。
注意:第二次编译才会生成二进制指令,第一次编译仅仅是在编译器内部生成一个用于描述模板的数据结构。
3、函数模板的隐式推断
函数模板虽然可以手动实例化,但使用麻烦,因此一般都根据参数类型进行隐式推断模板的参数。
注意:不能隐式推断的三种情况
1、函数参数与模板类型参数没有关系
2、不允许隐式类型转换
3、返回值类型不能隐式推断

4、函数模板与默认形参之间有冲突。
5、普通函数与同名的模板函数构成重载,编译器会优先调用普通函数。
注意:一般char*类型都需要特化。

三、类模板
1、类模板的定义
Template<typename M,typename R,typename A…>
Class Test
{
Public:
M val;
Test(A a)
{
0 var;
}
R func(void)
{
}
};
2、类模板的使用
注意:类模板的参数不支持隐式推断,必须显示指定类型参数。
类名<类型…>对象;
类模板分为两步进行实例化:
编译期:编译器将类模板实例化类,并生成类对象创建指令。
运行期:处理器执行类对象创建指令,将类实例化为对象。
类模板也是一种静态多态。

类模板中,只有那些被调用的成员函数才实例化,即产生二进制指令(调用谁实例化谁)。
3、类模板的静态成员
静态成员需要在类外定义,这一点不改变,但与普通类的定义不同。
Template<typename…> 类型 类名<…>::成员名;
4、递归实例化
类模板的参数可以是任何类型,只要该类型提供类模板所需要的功能。
类模板的实例化是一个有效的类型了,因此它也可以当做类模板的参数,叫递归实例化。
Vector<Vector> //二维数组
Test<Test>
5、类的局部转化
当类的某个成员函数不能通用,需要对特殊类型(char*)实现一个特殊的版本,叫类的局部特化。
template<>返回值类型 类名<类型>::函数名(参数)
{

}
注意:在类外实现
6、全类特化
当需要针对某种类型对类全部实现一个特殊版本,这叫类的全部特化。
template<>类名<类型>
{
};
7、类模板的缺省值
类模板的类型参数可以设置默认值类型,规则与函数的默认形参基本一致(设置缺省形参靠右)。
后面的类型参数可以使用前面的类型,但前面不能使用后面的。
8、普通数据也可以作为模板参数
template<typename T,类型B>
{
int arr[B];
}
给类模板一个数据,在类中就可以像使用宏名一个使用参数
注意:实例化类中提供的数据必须是常量。


一、模板的技巧
1、不能直接使用模板父类中的成员,需要:类名::函数名
2、typename可以用class代替
3、在类模板中,可以定义虚函数(多态),虚函数不能是模板函数
二、STL介绍
STL是标准模板库
容器:用来存储各类型数据的数据结构,
迭代器:类似于专门指向容器成员的指针,用来遍历、操作、管理容器中的成员,可以大大提高容器的访问速度。
算法:STL实现了常见的排序、查找算法。

List:双端链表容器
Iterator:用来指向容器中的元素
begin()获取指向第一个元素的迭代器
end()获取指向最后一个元素的下一个位置的迭代器
get_allocator()

vector:向量容器,俗称数组
stack、queue:栈和队列
deque:双端队列,可以在头部和尾部快速插入和删除,用法和向量基本一致。
注意:vector和deque是支持[ ]运算,因此不需要迭代器,其他容器一律使用迭代器进行遍历。
set:集合容器,集合中的数据会自动排序,不能重复。
map:是一种关联容器,在其他编程语言当中叫字典,C++叫映射,以key/value 键/值对的方式进行存储,key的值不能重复
mutimap:多重映射,它与map的值很像,区别是他的key值需要重复
multiset:多重集合,它与set很像,区别是他的值可以重复。
priority_queue:优先队列,它会根据元素的比较结果进行排序。
总结:
1、vector和deque是支持[]运算,因此不需要迭代器进行遍历,其他容器需要。
2、stack、queue、priority_queue容器没有迭代器
3、set、multiset、priority_queue会,对元素进行排序,因为它存储元素支持比较运算符。
STL中常用的算法函数
使用时要加头文件:algorithm
查找:find、serch
排序:sort
复制:copy
删除:remove
比较:equal

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值