类模板特化

一、主模板

#include <vector> 
#include <stdexcept> 
 
template <typename T> 
class Stack { 
private: 

//  元素
std::vector<T> elems;  


public: 

// push  元素
void push(T const&);

// pop  元素   
void pop(); 

//  传回最顶端元素 
T top() const;

// stack  是否为空 
bool empty() const {  
return elems.empty(); 

}; 
 
template <typename T> 
void Stack<T>::push (T const& elem) { 

//  追加(附于尾) 
elems.push_back(elem);   
}  
 
template <typename T> 
void Stack<T>::pop () { 
if (elems.empty()) { 
throw std::out_of_range("Stack<>::pop: empty stack"); 

//  移除最后一个元素 
elems.pop_back(); 

 
template <typename T> 
T Stack<T>::top () const { 
if (elems.empty()) { 
throw std::out_of_range("Stack<>::top: empty stack"); 

//  传回最后一个元素的拷贝 
return elems.back(); 


二、针对string的特化后的模板

你可以针对某些特殊的  template arguments, 对一个  class template 进行 「特化」 。 class templates 的特化与   function template  的重载类似,使你得以针对某些特定类型进行程序代码优化,  或修正某个特定类型在  class template  实例(instantiation) 中的错误行为 。 然而如果你对一个  class template 进行特化,就必须特化其所有成员函数。虽然你可以特化某个单独的成员函数,但一旦这么做,也就不再是特化整个  class template。


欲特化某个class template,必须以template<>  开头声明此一class,后面跟着你希望的特化结果。特化类型(specialized type)将作为template arguments 并在class名称之后直接写明: 
template<> 
class Stack<std::string> { 
... 
};  


对特化体(specializations)而言,每个成员函数都必须像常规的(一般的)成员函数那样定义, 每一个  T  出现处都必须更换为特化类型(specialized type): 
void Stack<std::string>::push (std::string const& elem) { 
elems.push_back(elem); //  将传入的  elem  附加于尾 
}


下面是一个针对  std::string  类型而特化的  Stack<>  的完整范例: 
 
#include <deque> 
#include <string> 
#include <stdexcept> 
#include "stack1.hpp" 
 
template<> 
class Stack<std::string> { 
private: 

//  元素 
std::deque<std::string> elems;   


public: 

// push  元素
void push(std::string const&); 

 // pop  元素 
void pop();

//  传回  stack  最顶端元素  
std::string top() const; 

// stack  是否为空 
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();

 
此例之中,我们在stack内部改用deque代替vector来管理元素。这么做并没有特别的好处,但它示范「一个特化实作码可以和其primary template(主模板。注:最原始的那一份定义)有相当程度的差异」。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值