欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

模板的类型萃取

程序员文章站 2022-06-10 13:42:45
...

铺垫一下萃取的基础点:

POD:指C风格的struct结构体定义的数据结构,且struct结构体中只能含有常规的数据类型,不能函数自定义类型;
函数重载:参数名相同,参数列表不同,返回类型可相同可不相同;
模板的特化:模板参数在某个特定类型的具体实现,分为全特化和偏特化。

类模板特化:

template <class T1 , class T2>
class Date
{
public:
    Date(T1 year , T2 month)
        :_year(year)
        ,_month(month)
    {
        cout << "模板类"<<endl;
    }
public:
    T1 _year;
    T2 _month;
};

template <>
class Date<int,int>
{
public:
    Date(int year, int month)
        :_year(year)
        , _month(month)
    {
        cout << "全特化" << endl;
    }
public:
    int _year;
    int _month;
};

template <class T1>
class Date<T1,int>
{
public:
    Date(T1 year, int month)
        :_year(year)
        , _month(month)
    {
        cout << "偏特化" << endl;
    }
public:
    T1 _year;
    int _month;
};

函数模板特化
注意:函数模板特化不支持偏特化,错误是非法使用显式模板参数

template <class T1,class T2>
void swap(T1 a, T2 b)
{
    int tmp = a;
    a = b;
    b = tmp;
    cout << "模板函数" << endl;
}

template <>
void swap<int, int>(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
    cout << "全特化" << endl;
}
错误的:
//template <class T1,class T2>
//void swap<T1,int>(T1 a,int b)
//{
    //int tmp = a;
    //a = b;
    //b = tmp;
    //cout << "偏特化" << endl;
//}

模板的类型萃取:为了有不同的方案对模板的不同类型进行实例化,可以提高效率。

问题:用模板编写顺序表时,会出现空间不够扩容,拷贝数据的情况——空间扩充之后直接memcpy函数将源数据段的内容拷贝到新数据段。但这种情况只适合于如 int这些基本数据类型,那么对于string类型应该如何处理?

首先用图来了解一下基本类型(如int)和string类型的扩容拷贝数据情况。

模板的类型萃取

基本数据类型可直接用memcpy函数进行数据的拷贝,string类型要用for循环一个一个对其进行赋值,如果在一个程序中既有内置类型又有string类型,如何在memcpy函数和for循环之间切换呢?这里就要用到模板类型的萃取。

//类型萃取
struct TRUEPOD  
{};
struct FALSEPOD
{};

template <class T>//模板类
class __Typetraits
{
    typedef  FALSEPOD IsPOD;
};
template <>//类特化
class  __Typetraits<int>
{
    typedef  TRUEPOD IsPOD;
};

template <class T>
T* __Copy(T* dst, const T*src, size_t n, TRUEPOD)
{
    return (T*)memcpy(dst, src, n*sizeof(T));
}
template <class T>
T* __Copy(T* dst, const T* src, size_t n, FALSEPOD)
{
    for (size_t i = 0; i < n; ++i)
    {
        dst[i] = src[i];
    }
    return dst;
}

template <class T>
T* Copy(T* dst, const T* src, size_t n)
{
    return __Copy(dst, src, n, __Typetraits<T>::IsPOD());
}

模板的类型萃取

模板优缺点总结:
优点:模板是复用的一种方式,复用代码节省了空间资源;增强了代码的灵活性。
缺点:模板让代码变得凌乱复杂,维护起来很麻烦,编译时间也会增长;而且出现编译错误时错误信息不但凌乱,还定位不准确。