ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++知识点59——类模板(4、类模板的模板参数是一个类模板)

2020-12-27 18:58:41  阅读:273  来源: 互联网

标签:知识点 CONT rval typename mystack 59 模板 const


接上一篇文章https://blog.csdn.net/Master_Cui/article/details/111824152

七、类模板的模板参数是一个模板类

 

类模板的模板参数本身可以是一个类模板,函数模板的模板参数不能是模板

依然用mystack作为示例,新的mystack的定义如下

template <typename T, int maxcount, 
	template <typename ELE, typename alloc=allocator<ELE>>
	typename CONT = deque>
class mystack
{
public:
	mystack();

	mystack(const mystack<T, maxcount, CONT> &rval);
	mystack<T, maxcount, CONT> &operator=(const mystack<T, maxcount, CONT> &rval);

	template <typename T2, int maxcount2, 
		template <typename ELE, typename alloc=allocator<ELE>>
		typename CONT2 = deque>
	mystack(const mystack<T2, maxcount2, CONT2> &rval);

	template <typename T2, int maxcount2, 
		template <typename ELE, typename alloc=allocator<ELE>>
		typename CONT2 = deque>
	mystack<T, maxcount, CONT> &operator=(const mystack<T2, maxcount2, CONT2> &rval);
	~mystack();
	void push(const T &ele);
	void pop();
	T top() const;
	bool empty() const {
		return elem.empty();
	}

private:
	CONT<T> elem;
};

 

上述代码中,类模板的第二个模板参数也是个类模板,参数是ELE,默认实参是deque。因为第二个参数也是个类模板,所以不能写成

template <typename T, int maxcount, 
	template <typename ELE, typename alloc=allocator<ELE>>
	typename CONT = deque<T>>

否则,编译器报错

容器也从CONT elem;变成了CONT<T> elem;第二个参数类模板模板参数依赖第一个模板参数进行实例化

上述代码中,deque作为模板参数有两个模板参数,当传入一个deque或者其他容器时,自带typename alloc,之后会对模板参数进行精确匹配,如果不写,就会导致模板参数typename alloc匹配不正确。

所以,即使alloc是个默认模板参数,typename ELE和typename alloc=allocator<ELE>也缺一不可,否则,当创建一个模板类的实例时,就会提示参数不匹配

mystack的实现细节如下,和上一篇文章差别不大

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
mystack<T, maxcount, CONT>::mystack()
{
	cout<<__func__<<endl;
}

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
mystack<T, maxcount, CONT>::mystack(const mystack<T, maxcount, CONT> &rval):elem(rval.elem)
{
	cout<<__func__<<endl;
}

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
mystack<T, maxcount, CONT> & mystack<T, maxcount, CONT>::operator=(const mystack<T, maxcount, CONT> &rval)
{
	cout<<__func__<<endl;
	if (this==&rval) {
		return *this;
	}
	this->elem=rval.elem;

	return *this;
}

template <class T, int maxcount, 
		template <typename ELE, typename alloc>
		typename CONT>
template <typename T2, int maxcount2, 
		template <typename ELE2, typename alloc2>
		typename CONT2>
mystack<T, maxcount, CONT>::mystack(const mystack<T2, maxcount2, CONT2> &rval)
{
	cout<<__func__<<endl;

	mystack<T2, maxcount2, CONT2> tmp=rval;
	elem.clear();
	while (!tmp.empty() && elem.size()<maxcount) {
		elem.push_front(tmp.top());
		tmp.pop();
	}
}

template <class T, int maxcount, 
		template <typename ELE, typename alloc>
		typename CONT>
template <typename T2, int maxcount2, 
		template <typename ELE2, typename alloc>
		typename CONT2>
mystack<T, maxcount, CONT> & mystack<T, maxcount, CONT>::operator=(const mystack<T2, maxcount2, CONT2> &rval)
{
	cout<<__func__<<endl;
	if ((void*)(this)==(void*)(&rval)) {
		return *this;
	}

	mystack<T2, maxcount2, CONT2> tmp=rval;
	elem.clear();
	while (!tmp.empty() && elem.size()<maxcount) {
		elem.push_front(tmp.top());
		tmp.pop();
	}

	return *this;
}

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
mystack<T, maxcount, CONT>::~mystack()
{
	cout<<__func__<<endl;
}

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
void mystack<T, maxcount, CONT>::push(const T &ele)
{
	if (elem.size()>=maxcount) {
		return;
	}
	//cout<<__func__<<endl;
	elem.push_back(ele);
}

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
void mystack<T, maxcount, CONT>::pop()
{
	//cout<<__func__<<endl;
	try {
		elem.pop_back();
	}
	catch (out_of_range &e){
		cout<<"out_of_range"<<endl;
	}
}

template <typename T, int maxcount, 
	template <typename ELE, typename alloc>
	typename CONT>
T mystack<T, maxcount, CONT>::top() const
{
	//cout<<__func__<<endl;
	try {
		return elem.back();
	}
	catch (out_of_range &e){
		cout<<"out_of_range"<<endl;
	}
}
int main(int argc, char const *argv[])
{
	mystack<int, 10, list> si10;
	for (int i=0;i<10;++i) {
		si10.push(i);
	}
	mystack<double, 20> sd20;
	for (int i=0;i<20;++i) {
		sd20.push(i);
	}
	si10=sd20;
    while(!si10.empty()) {
		cout<<si10.top()<<endl;
		si10.pop();
	}
	mystack<double, 10> sd10=si10;
	mystack<int, 10> si101=si10;
	return 0;
}

测试结果和前一篇文章相同

 

参考

《C++ Template》

《C++ Primer》

 

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

标签:知识点,CONT,rval,typename,mystack,59,模板,const
来源: https://blog.csdn.net/Master_Cui/article/details/111824185

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有