Welcome

首页 / 软件开发 / 数据结构与算法 / 泛型编程深入探索(二) 模板递归与可变参数模版

泛型编程深入探索(二) 模板递归与可变参数模版2016-03-19 NicWEI 以构建一个n纬网格为例,讲述模板递归。

首先是一个简单的一纬网格的实现,这个网格实现了规定长度的网格的实例化,并且能够在不同大小的网格类中自由的转型(通过模版嵌套的cast_ctr)

(使用到的技术,非类型参数模版,模版嵌套,类模版特例化,模版友元函数)

#include <cassert>#include <iostream>using namespace std;template <typename T,int LENGTH>class grid;template <typename T,int LENGTH>ostream& operator<< (ostream& os, const grid<T, LENGTH>& gd){os<<"[[grid with size: "<<gd.getSize()<<"] ";for(int i=0;i<gd.getSize()-1;i++){os<<gd[i]<<"	";}os<<gd[gd.getSize()-1]<<"]"<<endl;return os;}template <typename T,int LENGTH>class grid{public:grid():size(0),mCells(new T[LENGTH]){};grid(const grid<T,LENGTH>& gd):mCells(new T[LENGTH]),size(gd.size){for(int i=0;i<gd.size;i++){mCells[i]=gd.mCells[i];}}//足够,任何修改了t或者length的都会被这个嵌套模板handletemplate<typename E, int NEWLENGTH>//required E->T naturallygrid(const grid<E,NEWLENGTH>& gd):mCells(new T[LENGTH]),size(0){int newSize=LENGTH>gd.getSize()?gd.getSize():LENGTH;for(int i=0;i<newSize;i++){*(mCells+i)=gd[i];}size=newSize;}grid<T,LENGTH>& operator=(const grid<T,LENGTH>& gd){size=gd.getSize();T* su1= mCells;T* su2= gd.mCells;while(su1!=mCells+gd.size-1){*su1++=*su2++;}}template<typename E, int NEWLENGTH>//required E->T naturallygrid<T,LENGTH>& operator=(const grid<E,NEWLENGTH>& gd){int newSize=LENGTH>gd.getSize()?gd.getSize():LENGTH;for(int i=0;i<newSize;i++){*(mCells+i)=gd[i];}size=newSize;}inline int getSize()const {return size;}virtual ~grid(){delete mCells;mCells=nullptr;};T& operator[](int index){if(index>=size){resize(index+1);}return *(mCells+index);}const T& operator[] (int index)const{assert(index<getSize());return *(mCells+index);}void resize(int newSize,const T& def=T()){assert(newSize<=LENGTH);if(newSize<=size){size=newSize;}else {int i=size;for(;i<=newSize-1;i++){*(mCells+i)=def;}size=newSize;}}friend ostream& operator<< <T,LENGTH>(ostream& os, const grid<T, LENGTH>& gd);private:T* mCells;int size;};
测试代码如下:

#define _TEST_GRID_1#if _TEST_GRID_#include "grid.h"#include <iostream>#include <ctime>#include <cstdio>using namespace std;int main(){//网格实例化grid<int,20> a;srand((int)time(NULL));for(int i=0;i<20;i++){a[i]=rand()%30;}//不同大小,不同类型的网格互相拷贝grid<double,40>b(a);grid<double,10>c(a);cout<<a<<b<<c;//利用一纬网格,由调用方实现模版递归(实际是实例递归)grid<int,40> onegrid;grid<grid<int, 40>, 40> twogrid;unsigned long lct=time(NULL);for(int k=0;k<40;k++){srand((unsigned)(lct-clock()));for(int i=0;i<20;i++){twogrid[k][i]=rand()%30;}}cout<<twogrid;}#endif