模板的类型萃取
程序员文章站
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());
}
模板优缺点总结:
优点:模板是复用的一种方式,复用代码节省了空间资源;增强了代码的灵活性。
缺点:模板让代码变得凌乱复杂,维护起来很麻烦,编译时间也会增长;而且出现编译错误时错误信息不但凌乱,还定位不准确。
下一篇: wordpress下载主题安装方法解答