概念
模板是泛型编程的基础。所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式。模板分为模板函数和模板类。
模板函数
模板形参的定义可以用class也可以用typename
template<class T>
void fun(T a, T b)
{
printf("a b");
}
//重载模板函数
template<class T1, class T2>
void fun(T1 a, T2 b)
{
printf("a1 b2");
}
//实例化
void test()
{
int a = 1;
int b = 2;
double c = 3;
fun(a,b);
fun(a,c);
}
模板类
template<class T>
class SeqList
{
public:
SeqList();
~SeqList();
private:
int _size;
int _capacity;
T* _data;
};
template<T>
SeqList<T>::SeqList()
:_a(new T[10])
, _size(0)
, _capacity(10)
{
}
template<T>
SeqList<T>::~SeqList()
{
delete[] _a;
_a = NULL;
_size = 0;
_capacity = 0;
}
//实例化
void test()
{
SeqList<int> sl1;
SeqList<double> sl2;
}
模板函数和模板类的声明和定义需要放在同一个文件。
非类型的模板参数
浮点数和类对象不能作为非类型模板参数
例:求1+2+…+N,不能用乘除,时间复杂度O(1)
template<size_t N>
size_t myadd()
{
if(N&1 == 1) //当N为奇数,则N+1为偶数
{
char a[N][(N+1)>>1]; //N * (N+1) / 2 是等差数列求和公式
return sizeof(a);
}
else
{
char a[N>>1][N+1];
return sizeof(a);
}
}
模板参数
template<class T, class Container = SeqList<T>>
class Stack //Container是一个模板形参,模板实参传什么类型就是什么类型
{
public:
void Push(const T& x);
void Pop();
const T& Top();
bool Empty();
private:
Container _con;
};
Stack<int, SeqList<int>> S1;
模板的模板参数
template<class T, telmplate<class>class Container=SeqList>
class Stack
{
public:
void Push(const T& x);
void Pop();
const T& Top();
bool Empty();
private:
Container<T> _con;
};
Stack<int, SeqList> S;
类模板的特化
//以上面的SeqList<T>为例,特化SeqList<int>
template<>
class SeqList<int>
{
public:
SeqList();
~SeqList();
private:
int _size;
int _capacity;
int* _data;
};
//特化后的成员函数不需要模板形参
template<>
SeqList<int>::SeqList()
:_a(new int[10])
, _size(0)
, _capacity(10)
{
}
template<>
SeqList<int>::~SeqList()
{
delete[] _a;
_a = NULL;
_size = 0;
_capacity = 0;
}
//这是全特化,还有局部特化,有一个以上模板形参时,特化部分模板形参
template<class T1, class T2>
class AA{};
template<class T1>
class AA<T1, int>{};