C++知识点57——类模板(2、类模板的局部特化与默认模板实参)

本文接上一篇文章,介绍了C++类模板的局部特化,即只指定部分模板参数,局部特化的类模板仍是类模板,且只能对类模板进行局部特化。还阐述了类模板的默认模板实参,可为模板参数提供默认值,使用时不指定参数则采用默认值。

接上一篇文章https://blog.youkuaiyun.com/Master_Cui/article/details/111824064

四、类模板的局部特化

类模板可以被局部特化(只指定部分模板参数而不指定所有模板参数)。因为局部特化仍然保留着未指定的模板参数,所以,局部特化的类模板仍然是个类模板,而不是类模板的实例

此外,只能对类模板进行局部特化,不能对函数模板进行局部特化

示例

template <typename T1, typename T2>
class test
{
public:
	test(){cout<<__func__<<endl;}
};

template <typename T>
class test<T, T>
{
public:
	test(){cout<<"test<T, T>"<<endl;}
};

template <typename T>
class test<T, int>
{
public:
	test(){cout<<"test<T, int>"<<endl;}
};

template <typename T1, typename T2>
class test<T1 *, T2 *>
{
public:
	test(){cout<<"test<T1 *, T2 *>"<<endl;}
};

int main(int argc, char const *argv[])
{
	test<int, float> t1;
	test<float, float> t2;
	test<float, int> t3;
	test<int *, float *> t4;
	//test<int, int> t5;
	return 0;
}

第35行会产生二义性错误,因为会同时匹配class test<T, int>和class test<T, T>

 

五、类模板的默认模板实参

类模板可以为模板参数提供默认实参,比如可以为mystack提供默认的实现容器

template <typename T, typename CONT = deque<T>>
class mystack
{
public:
	mystack();
	mystack(const mystack<T, CONT> &rval);
	mystack<T, CONT> &operator=(const mystack<T, CONT> &rval);
	~mystack();
	void push(const T &ele);
	void pop();
	T top() const;
	bool empty() const {
		return elem.empty();
	}

private:
	CONT elem;
};

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

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

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

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

template <typename T, typename CONT> 
void mystack<T, CONT>::push(const T &elem)
{
	cout<<__func__<<endl;
	elem.push_back(elem);
}

template <typename T, typename CONT>
void mystack<T, CONT>::pop()
{
	cout<<__func__<<endl;
	try {
		elem.pos_back();
	}
	catch (out_of_range){
		cout<<"out_of_range"<<endl;
	}
}

template <typename T, typename CONT>
T mystack<T, CONT>::top() const
{
	cout<<__func__<<endl;
	try {
		return elem.back();
	}
	catch (out_of_range){
		cout<<"out_of_range"<<endl;
	}
}

上述代码就是mystack加了默认模板实参时候的代码,因为有两个模板参数,所以,所以类外实现的成员函数必须也有两个模板参数

使用带有默认模板实参的类模板时,如果不指定第二个参数,那么第二个参数默认使用deque

int main(int argc, char const *argv[])
{
	mystack<int> si;
	si.push(10);

	mystack<int, vector<int>> si2;
	si2.push(20);
	return 0;
}

 

参考

《C++ Template》

《C++ Primer》

 

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值