模板(三):模板之类型萃取(TypeTraits)

所谓理解 通常不过是误解的总和.
                               ——《斯普特尼克恋人》

 类型萃取,是C++中的一种编程技术。使用模板技术来萃取类型(包含自定义类型和内置类型)的某些特性,因为不同的类型具有不同的特性,当我们希望对模板传递的不同类型进行不同的操作的时候,同时我们又不希望改变该模板的封装方式。我们可以通过这种技术,对传入的不同类型进行不同的原理操作。

  这里我进行一个对于自创类SeqList类(对STL中vector的模拟)的类型萃取举例,情景说明:这里我想要对模板类SeqList进行拷贝,涉及到一个问题。如果我的元素类型是string的话,我必须进行深拷贝,否则就会出现崩溃的情况,这是对内存的使用出现问题。当我的元素类型是int、float、char等平凡类型(即POD:plain old data,基本类型,指在C++ 中与 C兼容的类型,可以按照 C 的方式处理,这些类型的拷贝不会涉及到内存的使用异常),我就可以使用浅拷贝,这样比起深拷贝提高了效率。
这个时候,我通过在SeqList类中进行类型萃取,就可以实现两种不同的拷贝方式:

//定义两个空类
struct __TrueType{};
struct __FalseType{};

//一般类型及特化(内嵌重定义IsPODType)
template<class T>
struct __TypeTraits{ typedef __FalseType IsPODType; };

template<>
struct __TypeTraits<int>{ typedef __TrueType IsPODType; };

//实现功能函数(用__TrueType/__FalseType实现重载)
template <class T>
T* __TypeCopy(T* dst, const T* src, size_t n, __TrueType){
    cout << "__TrueType:" << typeid(T).name() << endl; 
    return (T*)memcpy(dst, src, n*sizeof(T));   //浅拷贝,调用memcpy
}
template <class T>
T* __TypeCopy(T* dst, const T* src, size_t n, __FalseType){

    cout << "__TrueType:" << typeid(T).name() << endl;
    for (size_t i = 0; i < n; ++i){     //深拷贝,进行了 operator= 调用
        dst[i] = src[i];
    }
    return dst;
}
//对外接口(实现IsPODType的__TrueType和__FalseType的转换)
template <class T>
T* TypeCopy(T* dst, const T* src, size_t n){
    return __TypeCopy(dst, src, n, __TypeTraits::IsPODType());
}

int main(){
    int a1[3] = { 1, 2, 3 };
    int a2[3] = { 0, 0, 0 };
    string s1[3] = { "1", "2", "3" };
    string s2[3] = { "0", "0", "0" };

    TypeCopy(a1, a2, 3);
    TypeCopy(s1, s2, 3);
    return 0;
}
//typeid可以获取到一个类型的名称,但是不能拿来做变量的声明。

类型萃取流程图
模板(三):模板之类型萃取(TypeTraits)_第1张图片

注意
__TypeTraits::IsPODType是一个类型,类型加一个括号生成一个匿名对象,对象才能在函数中传参,函数的参数传参是传对象,所以类型加括号生成匿名对象传给形参.

  
  
模板(一):模板与非类型模板参数&模板的模板参数
模板(二):模板的特化与模板的分离编译

你可能感兴趣的:(C,plus,plus)