模板特化

前言:

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;
    
时间: 2025-01-09 03:20:16

模板特化的相关文章

C++模板特化编程

在C++中,模板特化是除了类之外的一种封装变化的方法.模板特化可以通过编译器来对不同的模板参数生成不同的代码. 模板特化通常以模板结构体作为载体.常用技法包括:类型定义.静态成员常量定义和静态成员函数定义. 从不同的角度来看待模板特化,模板特化可以扮演以下角色: 一.函数 模板结构体可以被看做一种函数,其参数必须是明确的类型.整数或者变长参数.变长参数展开甚至可以递归. 二.分支 模板结构体可以实现判断模板参数的类型来完成不同的工作.在编程的时候,如果碰到类似“如果类型是A时进行a操作,如果类型

函数模板特化

#include <iostream> template <typename T> T max(T x, T y) { return x > y ? x : y; } //函数模板特化 template <> const char* max(const char* x, const char* y){ return strcmp(x, y) > 0 ? x : y; } int main(){ std::cout << max(1, 2); st

C++ 模板特化以及Typelist的相关理解

近日,在学习的过程中第一次接触到了Typelist的相关内容,比如Loki库有一本Modern C++ design的一本书,大概JD搜了一波没有译本,英文版600多R,瞬间从价值上看到了这本书的价值!!这是题外话.这本书十分经典.其内容对于一个C++新手来说需要时间来理解吸收.在这里记录一下自己的理解.日后发现错误会给予更正.如有有人碰巧看到了.欢迎指正. 参考了http://blog.csdn.net/gatieme/article/details/50953564 整篇内容分了三个部分:1

C++ Primer 学习笔记_84_模板与泛型编程 --模板特化

模板与泛型编程 --模板特化 引言: 我们并不总是能够写出对全部可能被实例化的类型都最合适的模板.某些情况下,通用模板定义对于某个类型可能是全然错误的,通用模板定义或许不能编译或者做错误的事情;另外一些情况下,能够利用关于类型的一些特殊知识,编写比从模板实例化来的函数更有效率的函数. compare函数和 Queue类都是这一问题的好样例:与C风格字符串一起使用进,它们都不能正确工作. compare函数模板: template <typename Type> int compare(cons

C++程序设计方法4:模板特化

模板参数的具体化/特殊化 有时,有些类型不适用,则需要对模板进行特殊化处理,这称为"模板特化" 对函数模板,如果有多个模板参数,则特化时必须提供所有参数的特例类型,不能部分特化: 如: char *sum(char *,char *); 在函数名后用<>括号括起具体类型 template<> char* sum<char*>(char* a,char* b){...} 由编译器推导出具体的类型,函数名为普通形式: template<> c

C++ 模板特化

1.模板特化的定义 C++中的模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化.模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化. 1.1函数模板特化 函数模板特化是在一个统一的函数模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本.查看如下例: #include <iostream> using namespace std; template<typename T> T Max(T t1,T

C++ Primer 学习笔记_85_模板与泛型编程 --模板特化[续]

模板与泛型编程 --模板特化[续] 三.特化成员而不特化类 除了特化整个模板之外,还可以只特化push和pop成员.我们将特化push成员以复制字符数组,并且特化pop成员以释放该副本使用的内存: template<> void Queue<const char *>::push(const char *const &val) { char *new_item = new char[sizeof(val) + 1]; strncpy(new_item,val,sizeof(

C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解

代码编译运行环境:VS2012+Debug+Win32 模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始化.模板的实例化分为隐式实例化和显示实例化. 对函数模板的使用而言,分为两种调用方式,一种是显示模板实参调用(显示调用),一种是隐式模板实参调用(隐式调用).对于类模板的使用而言,没有隐式模板实参和显式模板实参使用的说法,因为类模板的使用必须显

模板特化和偏模板特化例子(template specialization and partial template specialization)

测试环境: win7 64 g++ 4.8.1 /*********************************************************************************   Copyright (C), 1988-1999, drvivermonkey. Co., Ltd.   File name:    Author: Driver Monkey   Version:    Mail:[email protected]   Date: 2014.04

C++ template —— 模板特化(五)

本篇讲解模板特化------------------------------------------------------------------------------------------------------------第12章 特化和重载------------------------------------------------------------------------------------------------------------前面几篇博客讲解了C++模板如何