3.3 类模板的特化
你可以用模板实参来特化类模板。和函数模板的重载类似,通过特化类模板,你可以优化基于某种特定类型的实现,或者克服某种特定类型在实例化类模板时所出现的不足 。另外,如果要特化一个类模板,你还要特化该类模板的所有成员函数。虽然也可以只特化某个成员函数,但这个做法并没有特化整个类,也就没有特化整个类模板。
为了特化一个类模板,你必须在起始处声明一个template<>,接下来声明用来特化类模板的类型。这个类型被用作模板实参,且必须在类名的后面直接指定:
template<>
class Stack {
...
}
进行类模板的特化时,每个成员函数都必须重新定义为普通函数,原来模板函数中的每个T也相应地被进行特化的类型取代:
void Stack::push (std::string const& elem)
{
elems.push_back(elem); //附加传入实参elem的拷贝
}
下面是一个用std::string特化Stack<>的完整例子:
//basics/stack2.hpp
#include
#include
#include
#include "stack1.hpp"
template<>
class Stack {
private:
std::deque elems; // 包含元素的容器
public:
void push(std::string const&); // 压入元素
void pop(); // 弹出元素
std::string top() const; // 返回栈顶元素
bool empty() const { // 返回栈是否为空
return elems.empty();
}
};
void Stack::push (std::string const& elem)
{
elems.push_back(elem); // 把传入的实参elem附加到末端
}
void Stack::pop ()
{
if (elems.empty()) {
throw std::out_of_range
("Stack::pop(): empty stack");
}
elems.pop_back(); // 删除末端元素
}
std::string Stack::top () const
{
if (elems.empty()) {
throw std::out_of_range
("Stack::top(): empty stack");
}
return elems.back(); // 返回末端元素的拷贝
}
在上面的例子里,我们使用了一个deque,而不是vector,来管理stack内部的元素。我们使用这种用法并不在于获得某种好处 ,而只是为了说明:特化的实现可以和基本类模板(prinmary template)的实现完全不同。