模板是C++一个非常重要的特性,它是C++泛型编程的基础。C++引入模板的一个重要原因是算法的重用。
一、函数模板
1.定义函数模板
(1)定义模板类型形参
template<typename T>
int comp(const T &v1,const T &v2){//比较两个变量的大小的函数模板
if(v1<v2) return -1;
if(v2<v1) return 1;
return 0;
}
tepename关键字后面跟形参类型T,一般情况下typename 和class具有相同的含义。但是使用typename更为直观。typename时C++的标准旧的程序可能只用关键字class.
typanme还用在模板内部指定类型
:
typename T::size_type 说明size_type是一个类型而不是一个变量。
(2)定义非类型模板形参
template<typename T,size_t n>
void arr_init(T (¶)[n]){//初始化一个数组
for (int i = 0;i != n;++i)
{
para[i] = 0;
}
}
二、类模板
定义类模板
template<typename T>
class queue{
public:
queue();
Type& front();
const Type& front()const;
void push(const Type&);
void pop();
bool empty()const;
private:
...
};
三、模板实例化
1、类模板的实例化
类模板->实例化T->T类型独立的新类->实例化->对象:queue<int> q;
2、函数模板的实例化
在调用的时候实例化:
comp(1,2)//实例化2个int类型的形参的函数
comp(1.0,2.0)//实例化2个double类型的形参的函数
类型形参匹配:
comp('s',1);
//第一个实参推断出时char型,第二个参数推断是int型,模板实参匹配失败
四、类模板成员
1、类模板成员函数
类模板中的成员函数也是模板函数,
在实例化类模版成员函数的时候,编译器不执行模版实参推断,相反,类模版成员函数的形参由调用该函数对象的类型确定。
2、类模板中的友元声明
(1)普通友元
template<typename Type>
class A{
friend class B;
friend comp();
//...
};
(2)一般模板友元
template<typename Type>
class A{
template<typename T> friend class B;
template<typename T> friend comp();
//...
};
这种友元的声明使用与类本身不同的类型参数也就是说所有类B的实例/comp()的实例都可以访问A的私有成员。
(3)特定的模板友元
template<typename T> friend class B;
template<typename T> friend comp();
template<typename Type>
class A{
friend class B<T>;
friend comp<T>();
//...
};
和(2)比较,这种友元的声明说明只有类型为T的实例才可以访问A的私有成员。
3、成员模板
成员函数模板和一般的函数模板一样,只不过他是类里面的函数模板。成员函数一个典型的例子是标准容器里的接受两个迭代器的assign成员函数和构造函数。assign函数接受不确定类型的迭代器来改变当前的容器。
vector<int> ivec;
list<int> lis2
list<int> lis;
lis.assign(ivec.begin(),ivec.end());
lis.assign(lis2.begin(),list2.end());
//assign成员函数为成员模板
成员模板定义
template<typename Type> template<typename T>
void A<Type>::comp(const T &v1,const T &v2){
...
}//先是类模板的类型,再是成员函数模板的类型。