类模板的特化

时间:2014.01.16

地点:基地——终于搬回基地实验室了,好冷啊!

——————————————————————————————————

一。简述

  通常来说,常规的模板具有很高的通用性,对各种数据类型都适用,就像通用计算机。但有时针对某一数据类型,我们需要特殊处理,于是我们不得不针对这一特定数据类型专门打造,但对于用户来说,看起来又都一样,因此我们需要对类模板进行特化。当然函数模板也可以特化。另外类模板的实例化有一个潜在问题,就是代码膨胀。每实例化一次,实例化的代码段就会被添加到程序代码空间来,使用类模板特化技术可以有效减少代码膨胀的问题。

二、基本概念

  主类模板,通俗来讲,就是那个最通用,泛化最强的模板。

  完全特化:也称绝对特化,即直接对某一具体类型做特殊化处理。

  部分特化:顾名思义,只特殊化部分参数,比如类型的某种特征:指针形式或者引用形式等

三、实例

  下面模板类使用容器构建一个栈Stack,首先我们构建一个主类模板,所有模板的特化工作也是在该主类模板的基础上进行的。

template<typename T>
class Stack{
private:
	vector<T> elems;
public:
	void push(const T &item){
		elems.push_back(item);
	}
	void pop(){
		if (elems.empty()) return;
		elems.pop_back();
	}
	T top() const{
		if (elems.empty()) return NULL;
		return elems.back();
	}
};
现在我们想对模板特殊化一点,即当模板参数为string类型时,我们并不想要和上述一样的行为,比如我们想要用deque容器来实现存放元素,在这个代码段中,特化模板只针对这一个具体的类型。属于完全特化,完全特化首行的尖括号内容须为空。

template<>
class Stack<string>{
private:
	deque<string> elems;
public:
	void push(const string &item){
		elems.push_back(item);
	}
	void pop(){
		if (elems.empty()) return;
	}
	string top() const{
		if (elems.empty()) return NULL;
		return elems.back();
	}
};

有时,我们也并不需要完全特化,而是就某一类型的某种特征而做特殊处理,比如我们想要T*做点特殊处理,那么行首尖括号中的T还是必须的,但后面参数须加上对T*的声明,以此表明当类型为T*时,我们不是采用主类模板的代码。一下是用list来存储对象的部分特例化实例

template<typename T>
class Stack<T*>{
private:
	list<T*> list;
public:
	void push(T* &item){
		list.push_front(item);
	}
	void pop(){
		if (list.empty()) return;
		list.pop_front();
	}
	T* top() const{
		if (list.empty()) return NULL;
		return list.front();
	}
};

四、总结

 当模板参数满足一些特殊条件时,我们使用特殊化模板来实例化,编译器会更具匹配精确度优先匹配精确度更高的实现,对于一般情形,任然使用主类模板进行实例化,一句话,特殊情况特殊处理,普通情况一般处理。



类模板的特化

上一篇:训练Restricted Boltzmann Machine(RBM)十五个问题


下一篇:Linux下通过crontab调度脚本时脚本所使用的环境变量问题