用模板实参来特化类模板,和函数模板的重载类似,通过特化类模块,可以优化基于某种特定类型的实现,或者克服某种特定类型在实例化类模板时所出现的不足。另外,如果要特一个类模板,你还要特化该类模板的所有成员函数。虽然也可以只特化某个成员,但这个做法并没有特化整个类,也就没有特化整个类模板。
为了特化一个类模板,你必须在起始处声明一个template<>,接下来声明用来特化类模板的类型。这个类型被用作模板实参,且必须在类名的后面直接指定:
template <>
class Stack<std::string>{
....
};
进行类模板的特化时,每个成员函数都必须重新定义为普通函数,原来模板函数中的每个T也相应地被进行特化的类型取代:
下面来看下类模板特化的使用示例
//stack2.h
#ifndef STACK2_H
#define STACK2_H
#include <deque>
#include <string>
#include <stdexcept>
#include "stack1.h"
template<>
class Stack<std::string>{
private:
std::deque<std::string> elems; //元素
public:
void push(std::string const &elem); //在尾部添加元素
void pop(); //在尾部删除一个元素
std::string top() const; //栈顶元素
bool empty() const {
return elems.empty();
}
};
void Stack<std::string>::push(std::string const &elem)
{
elems.push_back(elem); //添加一个元素
}
void Stack<std::string>::pop()
{
if(elems.empty()) {
throw std::out_of_range("Stack<std::string>::pop(): empty stack");
}
elems.pop_back(); //删除一个元素
}
std::string Stack<std::string>::top() const
{
if(elems.empty()) {
throw std::out_of_range("Stack<std::string>::top():empty stack");
}
return elems.back();
}
#endif // STACK2_H
//stack2test.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include "stack2.h"
int main()
{
try {
Stack<int> intStack;
Stack<std::string> stringStack;
intStack.push(7);
std::cout << intStack.top() << std::endl;
intStack.pop();
stringStack.push("hello");
std::cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
} catch (std::exception const &ex) {
std::cerr << "Exception: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
return 0;
}
运行结果