刚刚我们接触过模板类,类似于这样的:
在这个类中,我们如何知道它是什么类型的呢?这里,我们可以在类中加入一个内嵌类型,如:
这样就可以知道它是用户自定义的还是本身类型就拥有的,我们用到了类型萃取的方式。我们把__IsPodType叫做内嵌型别。
当我们遇到其他类型时,就将__IsPodType定义为__FalseType;
当遇到自定义类型时,就将__IsPodType定义为__TrueType;
说起这种书写方式,将template<>称为类型的特化。
举一个实在点的例子吧:
#include<iostream>
using namespace std;
struct __TrueType
{
bool Get()
{
return true;
}
};
struct __FalseType
{
bool Get()
{
return false;
}
};
template<class __Tp>
struct TypeTraits
{
typedef __FalseType __IsPodType;
};
template<>
struct TypeTraits<int> //在这里,非自定义类型只列出了int,char,float等这几种,其实还有很多类型,像long long,double,unsigned char等等
{
typedef __TrueType __IsPodType;
};
template<>
struct TypeTraits<char>
{
typedef __TrueType __IsPodType;
};
template<>
struct TypeTraits<long>
{
typedef __TrueType __IsPodType;
};
template<>
struct TypeTraits<unsigned int>
{
typedef __TrueType __IsPodType;
};
template<>
struct TypeTraits<float>
{
typedef __TrueType __IsPodType;
};
template<class __Tp>
void Copy(const __Tp* src, __Tp* dst,size_t size,__TrueType)
{
memcpy(dst,src,size*sizeof(__Tp)); //拷贝的内置类型
}
template<class __Tp>
void Copy(const __Tp* src, __Tp* dst,size_t size,__FalseType)
{
int i = 0;
for(i = 0; i < size; i++)
{
dst[i] = src[i];
}
}
<span style="font-family: Arial, Helvetica, sans-serif;">// 使用萃取判断类型的Get函数判断是否是 POD类型来处理</span>
//template<class __Tp>
//void Copy(const __Tp* src, __Tp* dst,size_t size) //Copy的另外一种写法,不传入类型
//{
// if(TypeTraits<__Tp>::__IsPodType().Get()) //if判断就可以直接写一个函数,,是上述两个Copy的结合
// {
// memcpy(dst,src,size*sizeof(__Tp));
// }
// else
// {
// int i = 0;
// for(i = 0; i < size; i++)
// {
// dst[i] = src[i];
// }
// }
//}
template<class __Tp>
void print(const __Tp* arr,size_t size)
{
int i = 0;
for(i = 0; i < size; i++)
{
cout<<arr[i]<<" ";
}
}
int main()
{
int arr1[] = {1,3,5,7,9};
int arr2[10];
int size = sizeof(arr1)/sizeof(arr1[0]);
Copy(arr1,arr2,size,TypeTraits<int>::__IsPodType());
/*Copy(arr1,arr2,size);*/
print(arr2,size);
return 0;
}
以上是数组的拷贝,用了类型萃取的方式。详细一点说类型萃取技术的由来就是,由于c++模板中类的参数是抽象的,我们不能在模板类中直接获得它的具体特征,我们就用类型萃取(trait)的方式,来抽取类型的具体特征,知道它是什么类型,比如内置类型,自定义类型。
我们可以看到很多模板类的特化,这也是类型萃取的一个基本思想。