关闭

类模板特化

46人阅读 评论(0) 收藏 举报
分类:

一、主模板

#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(主模板。注:最原始的那一份定义)有相当程度的差异」。 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14644次
    • 积分:1218
    • 等级:
    • 排名:千里之外
    • 原创:112篇
    • 转载:6篇
    • 译文:0篇
    • 评论:0条