首页 > 代码库 > 模板特化

模板特化

前言:

C++提供了一种特例机制,对于某个已有模板,可以为某个或者某组模板参数类型另外指定一种变体,以应付原模板无法处理的问题,或者提供更高效的实现方案.这种机制就称为模板特例.

 

模板特例一个典型的例子就是C++标准库中的容器类模板vector<T>。与数组相似,vector是一种将数据连续存放的容器.但与数组不同的是,vector容量可随所存数据增加而自动增加.vecotr<bool>则是vector<T>的一个特例,专门为存储布尔型值设计.布尔型只有两个值,真或者假,只需要1比特即可表示.1字节完全可以用来存储8个布尔型变量.如果采用基于sizeof(T)的算法,则1个布尔值占用1字节,显得太浪费.

我们将vector<bool>设计成用一系列整数值来保存压缩后的布尔值.

具体见代码:

#include <cstdio>#include <iostream>#include <stdexcept>template<typename T>class my_vector{private:     T * array;     unsigned size;     unsigned block_size;public:    my_vector(unsigned bsz):array((T*)malloc(sizeof(T)*block_size),size(0),                              block_size(size){                              }    ~my_vector(){         if(array){               free(array);         }    }        void push_back(const T& v) throw (std::runtime_error){           if(size==block_size){                  block_size*=2;                  T *new_array=realloc(array,block_size*sizeof(T));                  if(new_array!=NULL){                        array=new_array;                  }                                    else{                         free(array);                         array=NULL;                         throw std::runtime_error("Out of memory.");                  }           }           array[size++]=elem;    }        T& operator[] (unsigned i) {return array[i];}    const T& operator[] (unsigned i) const{return array[i];}        //告诉我们占了多少内存    unsigned get_mem_size() const{return block_size*sizeof(T);}};template<>class my_vector<bool>{private:       int *array;       unsigned size;       unsigned block_size;       //一个段(segment)即一个整数值,段大小为一个整数值所能容纳的最多布尔值       const static unsigned seg_size;public:       my_vector(unsigned bsz):array((int*)malloc(sizeof(int)*bsz),size(0),                                                       block_size(bsz){                                                       }              ~my_vector(){              if(array){                    free(array);              }       }              void push_back(bool elem) throw (std::runtime_error){               if(size==block_size){                     block_size*=2;                     int *new_array=(int*)realloc(array,sizeof(int)*block_size);                     if(new_array){                           array=new_array;                     }                                          else{                          free(array);                          array=NULL;                          throw std::runtime_error("Out of memory.");                     }                      }                             set(size++,elem);      }            void set(unsigned i,bool elem){             if(elem){                   array[i/seq_size] |=(0x1 << (i%seq_size));             }                          else{                   array[i/seq_size] &=~(0x1 << (i%seq_size));             }      }            bool operator[] (unsigned i) const{             return array[i/seq_size] & (0x1 << (i%seq_size))!=0;      }            unsigned get_mem_size() const{            return block_size* sizeof(int);      }};const unsigned my_vector<bool>::seq_size =sizeof(int)*8;    

 

模板特化