1.定义模板
1.1函数模板
template<模板参数列表>
返回值 函数名(形参列表)
实例化函数模板
通过形参列表来推导出模板参数的实参。
模板类型参数
A类型模板参数
template<typename T>
typename T 为模板类型参数
B非类型模板参数
template<类型 a>
类型有所限定,如果是非引用或指针是整型, 有引用或指针必须有静态生存期。
编写类型无关的代码
为了达到泛型编程的目的,适用范围广,有两个原则
!模板中的函数参数是const的引用
! 函数题中的条件判断仅使用<比较运算
模板应尽量减少对实参的要求
模板的编译
模板是在编译期间实例化,第一步先检查语法,第二步实例化
1.2 类模板
类模板的定义
template<typename T>
class 类名
{
...
};
实例化类模板
类模板必须通过显示模板参数来实例化,并且每一个实例直接互相不关联。
类模板成员函数的实例化
定义前面要加上template<typename T>
在类代码内简化模板类名的使用
如果在类内可以不使用要有模板的类名
template<typename T>
class A{
A();//也可以A<T>();
A& operator ++();
};
在类模板外使用类模板名
与上面相对应,如果A()在模板外定义
template<typename T>
A<T>& A<T>::operator++(){}
其中有了A<T>::的类作用域声明或在函数中可以上在类内一样不用在类后加上类型。
类模板和友元
一对一的友元
template <tynename> class BlobPtr;
template<typename T>
class{
friend class BlaobPtr<T>;
}
两个类型参数相同
通用和特定的模板友好关系
template<typename T>class Pal;
class C{
friend class Pal<X>;//所有的Pal都是友元,并且不用前项声明。
}
令模板自己的类型参数成为友元
template<typename Type> class Bar{
friend Type;//用那个实例化,那个将成为他的友元 ,内置类型也可以。
};
类模板的static成员
每个实例有一个静态成员,通过类名 或 对象访问。
默认模板实参
和函数的默认相似
控制实例化
extern template declaration;//声明 在有定义的cpp文件生成模板实例
template declaration;//定义在该cpp生成模板。
这种实例化模板声明会实例(定义)所有的成员,所以必须保证所以类型都可以以应用于成员函数。 (普通的类模板实例是部分实例,用那个成员实例化哪个)
1.3模板的实参推断
类型转换与模板类型参数
支持转换类型
!const转换 非const的引用或指针可以向const转换
! 数组向指针转换 (函数参数不是引用类型)
其他类型都不可以比如 double向int转换
函数模板的显示实参
类似与类的实例化 函数名<显示模板参数类型>
这种支持一般的转换
尾置返回类型与类型转换
略
模板的特化
template<>
class stack<string>{
};
对于某种不可以转换的类型可以将其特化为可以转换的类型
还可以添加功能(成员)
模板的特例本质是模板的实例化与函数的重载不同。
模板的偏(部分)特化
类模板可以,函数模板不能,
template<typename T>
class stack<T&>{
};
泛型编程
关联特性
是把一种类型提示为更大内存的类型 ,让程序的运行更加的同用。
迭代器
Iterators(迭代器)是算法和容器的桥梁。将迭代器作为算法的参数、通过迭代器来访问容器而不是把容器直接作为算法的参数。迭代器事故STL中的枢纽。
。
容器
vector
deque
list
stack
queue
map和Multimup
set和multiset
使用查表即可