模板参数-实现容器适配器
我们在学习栈和队列时,通过数组或链表实现,这里C++提供一种实现方式:容器适配器.
用vector或者list为容器,适配出一个stack或queue,具体是如何实现?
基本思想:通过vector或list提供的接口,适配出stack或者deque.
template <class T, class Container = SeqList<T>>
class T:
表示栈中要存什么类型的数据
class Container:
表示实现栈的容器是什么类型
a) 利用模板参数实现容器适配器
//template <class T, class Container = SeqList<T>>
template <class T, class Container = SeqList<T>>
class Stack{
public:
void Push(const T& x){
_con.PushBack(x);
}
void Pop(){
_con.PopBack();
}
const T& Top(){
int sz = _con.GetSize() - 1;
return _con[sz];
}
bool Empty();
private:
Container _con;
};
Stack<int, SeqList<int>> dd;
这种场景会怎样?
Stack<int, SeqList<char>> dd;
指定传参时,如果给模板的类型域与给容器的不一致,可能就会出现问题,C++提供这样一种方式:模板类的模板参数
b) 模板类的模板参数
//template <class T, template<class> class Container>
template <class T, template<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> dd;
再按照上面实例化就会compile error
template<class>
表示Container是一个模板类类型的模板形参
非类型的类模板参数
模板参数分类类型形参与非类型形参
类型形参:出现在模板参数列表中,在class或者typename之后的参数类型名称
非类型形参:用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用
a) 非类型的类模板参数
静态顺序表
template <typename T, size_t MAX_SIZE = 10> //带缺省模板参数
class SeqList{
public:
SeqList();
private:
T _array[MAX_SIZE];
int _size;
};
template <typename T, size_t MAX_SIZE>
SeqList<T, MAX_SIZE>::SeqList() : _size(0) {}
void test1()
{
SeqList<int> s1;
SeqList<int,20> s2;
}
b) 非类型的函数模板参数
template <class T,int value>
T Add(const T& x)
{
return x + value;
}
- 非类型的模板参数必须在编译期就能确认结果
- 非类型的模板参数仅限于int、enum、指针、引用