C++知識點57——類别範本(2、類别範本的區域性特化與預設模板實參)

Master Cui發表於2020-12-27

接上一篇文章https://blog.csdn.net/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》

 

歡迎大家評論交流,作者水平有限,如有錯誤,歡迎指出

相關文章