类型萃取

一、类型萃取(类模板特化应用)
Q:如何实现一个通用的拷贝函数?
1.使用memcpy函数

template<class T>
void Copy(T* dst,const T* src,size_t size)
{
   memcpy(dst,src,sizeof(T)*size);
}

上面实现虽然任意类型的空间都可以拷贝,但是自定义类型有可能涉及到深拷贝,而memcpy是浅拷贝,可能会出错。如果对象中涉及到资源管理,就只能用赋值。

2.使用赋值方式拷贝

template<class T>
void Copy(T* dst,const T*src,size_t size)
{ 
   for(size_t i=0;i<size;++i)
   {
     dst[i]=src[i];
   }
}

用循环赋值的方式可以实现,但是效率很低。
因此考虑实现遇到内置类型用memcpy拷贝,遇到自定义类型用循环方式来做
3.增加bool类型区分自定义与内置类型

template<class T>
void Copy(T* dst,const T* src,size_t size,bool IsPodType)
{
   if(IsPodType)
      memcpy(dst,src,sizeof(T)*size);
   else
   {
      for(size_t i=0;i<size;++i)
        dst[i]=src[i];
   }
 }

通过多传递一个参数,可将上面两种拷贝的优势结合起来。但是缺陷是:用户要根据所拷贝元素的类型去传递参数,会有出错的可能。所以我们考虑是否能够让函数自动识别是哪种类型。
4.使用函数区分内置与自定义类型

//Pod:代表基本类型
//此处举例,只列出部分类型
bool IsPodType(const char* strType)
{
  const char* arrType[]={"char","short","int","long","float"};
  for(size_t i=0;i<sizeof(arrType)/sizeof(arrType[0]);++i)
     {
           if(0==strcmp(strType,arrType[i])
               return true;
      }
      return false;
}
template<class T>
void Copy(T* dst,T* src,size_t size)
{
   if(IsPodType(typeid(T).name())
        memcpy(dst,src,sizeof(T)*size);
   else
   {
        for(size_t i=0;i<size;++i)
            dst[i]=src[i];
   }
}

通过typeid确认实际类型,再在内置类型集合中枚举是否出现过,就可以确认所拷贝元素的类型。但缺陷是:枚举要将所有类型遍历一遍,效率较低。

5.类型萃取
为了区分内置类型与自定义类型,给出下面两个类代表自定义类型和内置类型

//内置类型
struct TrueType
{
  static bool Get()
  {
     return true;
  }
};
//自定义类型
struct FalseType
{ 
  static bool Get()
  {
    return false;
  }
};

给出以下类模板,之后可以对任何类型进行实例化

template<class T>
struct Type
{
  typedef FalseType IsPodType;
};

对上面的类模板进行实例化

template <>
struct Type<char>
{
  typedef TrueType IsPodType;
};

template<>
struct Type<short>
{
  typedef TrueType IsPodType;
};

template<>
struct Type<int>
{
 typedef TrueType IsPodType;
};

//对所有的内置类型都进行特化

通过对Type类模板的重写改写,来确认所拷贝对象的实际类型

//如果T为int类型,程序运行就会使用特化过的Type<int>,该类中的IsPodType是类TrueType,TrueType中Get函数返回true,实现内置类型用memcpy方式拷贝
//如果T为string类型,程序使用Type模板,该类模板中的IsPodType是FalseType,FalseType中Get函数返回false,实现自定义类型用赋值方式拷贝

template<class T>
void Copy(T* dst,T* src,size_t size)
{
  if(Type<T>::IsPodType::Get())
     memcpy(dst,src,sizeof(T)*size);
  else
  {
    for(size_t i=0;i<size;++i)
        dst[i]=src[i];
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值