定义
这些模板运算对象的类型不是实际的数据类型,而是一种参数化的类型,带类属参数的函数称为函数模板,带类属参数的类称为类模板。
函数模板
(而模板函数为函数模板的实例化)
template <typename T>
T Max(const T a,const T b)
{ return a>b?a:b; }
重载函数模板
(C++编译器将根据调用的参数类型和个数选择可用于实例化的函数模板)
template <typename T>
T Max(const T *a,int n){
T temp;
int i;
temp=a[0];
for(i=1;i<n;i++)
if(a[i]>temp) temp=a[i];
return temp;
}
用普通函数重载函数模板
template<typename T>
T Max(const T a,const T b)
{ return a>b?a:b; }
int Max(const char a,const int b)//Max(i,c) Max(c,i)都是正确的调用
{ return a>b?a:b; }
类模板
- 类属参数必须至少在类说明中出现一次
- 而模板类为类模板的实例化
template<typename Type>
class TClass{
//...
private:
Type DateMember;
//...
};
例子——数组类模板
- 类模板成员函数,如果在类中定义(作为inline函数),则不需要特别声明
- 如果在类外定义,则每个成员函数定义都要冠以模板参数说明,并且指定类名时要后跟类属参数
template<typename T>
class Array{
public:
Array(int s);
virtual~Array();
virtual const T & Entry(int index)const;
virtual void Enter(int index, const T &value);
protected:
int size;
T *element;
};
template<typename T>Array<T>::Array(int s){//满足上面两条要求
if(s>1) size=s;
else size=1;
element=new T[size];
}
template<typename T>Array<T>::Array()
{ delete[] element; }
template<typename T>const T & Array<T>::Entry(int index)const
{ return element[index]; }
template<typename T>void Array<T>::Enter(int index,const T & value)
{ element[index]=value; }
类模板作为函数参数
(当一个函数拥有类模板参数时,这个函数必定是函数模板)
template<typename T>
void Tfun(const Array<T>&x,int index)// 函数模板,类实例化后才能调用
{ cout<<x.Entry(index)<<endl; }
在类层次中的类模板
- 类模板可以是基类,也可以是派生类
- 类模板可以从类模板派生或普通类派生
- 模板类可以从类模板派生或普通类派生
- 一个类模板从普通类派生,意味着派生类增加了类属参数
- 一个模板类从类模板派生,意味着派生类继承基类时提供了实例化的类型参数
类模板与友元
- 一个函数或函数模板可以说明为类或类模板的友元函数
- 一个类或类模板可以说明为类或类模板的友元类
模板类的友元函数
//实例化后每个模板类的友元函数
templte <typename T> class X
{
//...
friend void f1();
}
//实例化后为特定类型的友元函数
template <typename T> class X
{
//...
template <typename T> friend void f2(X<T> &);
}
//实例化后 特定类函数 为其友元函数
template <typename T> class X
{
//...
friend voidA::f3();
}
//实例化后 另一个类模板的函数 为其友元函数
template <typename T> class X
{
//...
template<typename T>friend void B<T>::f4(X<T> &);
}
模板类的友元类
//实例化后 Y的每个成员函数为其友元函数
template<typename T>class X
{
//...
friend class Y;
}
//实例化后 Z特定类型的每个成员函数为其友元函数
template<typename T>class X
{
//...
template<typename T>friend class Z;
}
类模板与静态成员
若类模板中定义了静态数据成员,则实例化后的每个模板类都有自己的静态数据成员,该模板类的所有对象共享这个静态数据成员。
const double PI=3.14159;
template<typename T>class Circle{
T radius;
static int total;
public:
Circle(T r=0){
radius=r;
total++;
}
void set_Radius(T r)
{ radius=r; }
double Get_Radius()
{ return radius; }
double Get_Girth()
{ return 2*PI*radius; }
double Get_Area()
{ return PI*radius*radius; }
static int ShowTotal();
};
template<typename T>int Circle<T>::total=0;//类外赋值
template<typename T>int Circle<T>::ShowTotal()
{ return total; }
标准模板
容器
容器类型 | 包含 | 说明 |
---|---|---|
序列容器 | vector | 向量,可随机访问序列中的单个元素,在序列尾快速插入和删除元素 |
deque | 双向队列,随机访问序列中的单个元素,可以在序列头或尾快速插入和删除元素 | |
list | 双向链表,用动态链式存放数据,可以从任何位置快速插入和删除元素 | |
关联容器 | set | 集合,无重复值元素,可以快速查找 |
multiset | 集合,允许重复值元素,可以快速查找 | |
map | 映射,一对一映射,无重复元素,实现基于关键字的快速查找 | |
multimap | 映射,一对多映射,允许重复值元素,实现基于关键字的快速查找 | |
容器适配器 | stack | 堆栈,后进先出表,只能在表头插入和删除元素 |
queue | 队列,先进先出表,只能在表头删除元素,表尾插入元素 | |
priority_queue | 优先级最高的元素总是第一个出列 |
容器的共同操作
表达式 | 功能 |
---|---|
Container C | 构造容器 |
Container C(beg,end) | 以地址构造容器 |
Container c1(c2) | 以容器构造容器 |
c.~Container() | 析构容器 |
c1=c2 | 对象赋值 |
c1.swap(c2) | 交换同类型容器中的数据 |
c1 op c2 | 容器的关系运算,可以为==,!=,<,>,<=,>= |
c.size() | 返回容器元素个数 |
c.empty() | 判断容器是否为空 |
c.max_size() | 返回容器可容纳元素的最大数量 |
Container::iterator iter | 定义容器迭代器对象iter |
c.begin() | 首元素迭代器 |
c.end() | 尾元素迭代器 |
c.rbegin() | 逆向首元素迭代器 |
c.rend() | 逆向尾元素迭代器 |
c.insert(pos,elem) | 插入 |
c.erase(pos) | 删除 |
c.erase(beg,end) | 删除 |
c.clear() | 删除所有元素 |
序列容器多出操作
表达式 | 功能 |
---|---|
c.font() | 首元素 |
c.back() | 尾元素 |
c.push_back(elem) | 末端插入 |
c.pop_back() | 末端删除 |
c[i] | 访问元素 |
c.at(i) | 访问元素 |
迭代器
迭代器类别层次 | 容器 |
---|---|
输入,输出 | |
正向 | |
双向 | list,set,mulset,map,multimap |
随机访问 | vector,deque |
注:stack、queue、priority_queue容器是操作受限的列表,不支持迭代器
预定义迭代器 | 操作方向 | 功能 |
---|---|---|
iterator | 向前 | 读写 |
const_iterator | 向前 | 读 |
reverse_iterator | 向后 | 读写 |
const_reverse_iterator | 向后 | 读 |
算法
表达式 | 原型 | 功能 |
---|---|---|
find | template<typename InputIterator,typename T>inline | 迭代器中查找 |
InputIterator find(InputIterator first,InputInterator last,const T & value) | 迭代器指定位置查找 | |
find_if | template<class InputIerator, class T,class Predicate>inline | 迭代器中查找符合条件的第一个元素 |
InputIterator find_if(InputIerator first,InputIterator last,Predicate predicate) | 迭代器指定位置查找符合条件的第一个元素 | |
sort | templatevoid sort(RanIt first,RanIt last) | RanIt为随机访问迭代器 |
template<class RanIt,class Pred>void sort(RanIt first,RanIt last,Pred pr) | Pred 为二元逻辑函数 | |
binary_search | template<class RwdIt,class T> bool binary_search(FwdIt first,FwdIt last,const T &val) | 顺序,返回是否有,有则1,无则0 |
template<class RwdIt,class T,class Pred> bool binary_search(FwdIt first,FwdIt last,const T &val,Pred pr) | 逆序,返回是否有,有则1,无则0 |