POD:plain old data平凡类型—基本类型
自我理解POD类型萃取:就是对基本类型的提取,我们在实现一个通用的函数模板时有时对特殊的数据类型要采用特殊的函数体处理,而基本类型数据都可以通过实例化该函数得到想要的结果,所以我们可以将一般的类型提取出来
接下来,我们用程序实例来验证
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
class String//String类的深拷贝
{
public:
String(const char* pstr = "")
{
if(pstr==NULL)
{
_pstr = new char[1];
*_pstr = '\0';
}
else
{
_pstr = new char[strlen(pstr)+1];
strcpy(_pstr,pstr);
}
}
String(const String& s)
{
_pstr = new char[strlen(s._pstr)+1];
strcpy(_pstr,s._pstr);
}
String& operator=(const String& s)
{
if(this!=&s)
{
String pTemp(s);
delete[] _pstr;
strcpy(_pstr,pTemp._pstr);
}
return *this;
}
~String()
{
if(_pstr!=NULL)
{
delete[] _pstr;
_pstr = NULL;
}
}
private:
char* _pstr;
};
template<typename T>
void Copy(T* dst,T* src,size_t size)
{
memcpy(dst,src,sizeof(T)*size);
}
int main()
{
int array1[] = {1,2,3,4,5,6};
int array2[6];
Copy(array2,array1,sizeof(array1)/sizeof(int));//拷贝成功
String array3[] = {"1111","2222","3333","4444"};
String array4[4];
Copy(array4,array3,sizeof(array3)/sizeof(String));//两个数组元素的地址相同,即造成了浅拷贝
return 0;
}
上例中直接用memcpy函数处理数组array3和array4时会导致出错,于是我们用下面的Copy函数解决问题
template<typename T>
void Copy(T* dst,T* src,size_t size)
{
for(size_t idx=0; idx<size; ++idx)
{
dst[idx] = src[idx];
}
}
但对于int数组array1和array2,用上述函数效率太低。接下来我们引出类型萃取来解决,对于像ind double char …类型特化后的模板函数使用memcpy函数,
struct TrueType
{
bool Get()
{
return true;
}
};
struct FalseType
{
bool Get()
{
return false;
}
};
template<typename Tp>
struct TypeTraits
{
typedef FalseType IsPODType;
};
template<>
struct TypeTraits<int>
{
typedef TrueType IsPODType;
};
template<>
struct TypeTraits<char>
{
typedef TrueType IsPODType;
};
template<>
struct TypeTraits<float>
{
typedef TrueType IsPODType;
};
template<>
struct TypeTraits<double>
{
typedef TrueType IsPODType;
};
//使用参数推导的萃取处理
template<typename T>
void Copy(T* dst,T* src,size_t size,FalseType)
{
cout<<"FalseType:"<<typeid(T).name()<<endl;
for(size_t idx=0; idx<size; ++idx)
{
dst[idx] = src[idx];
}
}
template<typename T>
void Copy(T* dst,T* src,size_t size,TrueType)
{
cout<<"TrueType:"<<typeid(T).name()<<endl;
memcpy(dst,src,sizeof(T)*size);
}
int main()
{
int array1[] = {1,2,3,4,5,6};
int array2[6];
Copy(array2,array1,sizeof(array1)/sizeof(int),TrueType);
String array3[] = {"1111","2222","3333","4444"};
String array4[4];
Copy(array4,array3,sizeof(array3)/sizeof(String),FalseType);
getchar();
return 0;
}
或则使用萃取判断类型的Get函数判断是否是POD类型来处理
template<class T>
void Copy(T* src,T* dst, size_t size)
{
cout<<"TrueType:"<<typeid(T).name()<<endl;
if(TypeTraits<T>::IsPODType().Get())
{
memcpy(src,dst,sizeof(T)*size);
}
else
{
for(size_t idx=0; idx<size; ++idx)
{
dst[idx] = src[idx];
}
}
}
int main()
{
int array1[] = {1,2,3,4,5,6};
int array2[6];
Copy(array2,array1,sizeof(array1)/sizeof(int));
/*String array3[] = {"1111","2222","3333","4444"};
String array4[4];
Copy(array4,array3,sizeof(array3)/sizeof(String));
getchar();
return 0;
}