C++中的特化问题和类型萃取问题
程序员文章站
2022-06-10 14:38:31
...
模板的特化
概念
从字面上来解释,就是为已有的模板参数进行一些使其特殊化的指定,使得以前不受任何约束的模板参数,或受到特定的修饰(例如const或者摇身一变成为了指针,甚至是经过别的模板类包装之后的模板类型)或完全被指定了下来。
全特化:
就是模板中模板参数全被指定为确定的类型。全特化也就是定义了一个全新的类型,全特化的类中的函数可以与模板类不一样。
偏特化:
就是模板中的模板参数没有被全部确定,需要编译器在编译时进行确定。
全特化的标志就是产生出完全确定的东西,而不是还需要在编译期间去搜寻适合的特化实现
模板类全特化
template <class T1,class T2>
class KeyVal
{
protected:
T1 _key;
T2 _val;
};
//全特化
template<>
class KeyVal<int,char>
{
protected:
int _key;
char _val;
};
这里归纳下针对类模板特化的几种类型
- 一是特化为绝对类型;
- 二是特化为引用,指针类型;
- 三是特化为另外一个类模板。
模板类的偏特化
template <class T1,class T2>
class KeyVal
{
protected:
T1 _key;
T2 _val;
};
template<class T2> //局部特化
class KeyVal<int,T2>
{
protected:
int _key;
T2 _val;
};
template <class T1,class T2> //局部特化
class KeyVal<T1*,T2*>
{
protected:
T1 _key;
T2 _val;
};
从上面的例子可以看出局部特化偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
模板函数全特化
template <class T>
void Display(const T& x)
{
cout<<x<<endl;
}
template <>//模板函数全特化
void Display(const int& x)
{
cout<<x<<endl;
}
全局函数模板特化不能包含缺省的实参值。然而,对于基本(即要被特化的)模板所指定的任何缺省实参,显式特化版本都可以应用这些缺省实参值。
模板函数不支持局部特化。
全局特化和局部特化都没有引入一个全新的模板或者模板实例。它们只是对原来的泛型(或者非特化)模板中已经隐式声明的实例提供另一种定义。在概念上,这是一个相对比较重要的现象,也是特化区别于重载模板的关键之处。
类型萃取
当我们在写Vector和List的时候,遇到了这样的问题,在拷贝构造函数中和顺序表扩容时,当是内置类型我们可以直接使用memcpy把旧空间的内容考到新空间,但是当遇到strring类型时使用memcpy就会发生浅拷贝问题,会造成对一块空间同时析构多次。当时为了解决这个问题就统一使用了深拷贝。显然这样的解决方法不是最优的。如果我们可以确定类型,当是内置类型时就用memcpy,遇到string类型时就是用深拷贝。
类型萃取代码实现
struct __TrueType
{};
struct __FalseType
{};
template<class T>
struct TypeTraits
{
typedef __FalseType IsPodType;
};
template<class T>
T* __TypeCopy(const T* src,T* dst,size_t n,__TrueType)
{
cout<<"memcpy"<<endl;
return (T*)memcpy(dst,src,n*sizeof(T));
}
template<class T>
T* __TypeCopy(const T* src,T* dst,size_t n,__FalseType)
{
cout<<"for+operator= "<<endl;
for (size_t i=0; i<n; i++)
{
dst[i] = src[i];
}
return dst;
}
template<class T>
T* TypeCopy(const T* src,T* dst,size_t n)
{
return __TypeCopy(src,dst,n,TypeTraits<T>::IsPodType());
}
template<>
struct TypeTraits<int>
{
typedef __TrueType IsPodType;
};
template<>
struct TypeTraits<char>
{
typedef __TrueType IsPodType;
};
template<>
struct TypeTraits<double>
{
typedef __TrueType IsPodType;
};
template<>
struct TypeTraits<float>
{
typedef __TrueType IsPodType;
};
测试代码:
void TestType()
{
int srcint[5]={1,2,3,4,5};
int dstint[5];
string srcstr[3]={"11","22","33"};
string dststr[3]={};
TypeCopy(srcint,dstint,5);
TypeCopy(srcstr,dststr,3);
}
测试结果:
推荐阅读
-
MySQL 5.1中varchar类型中文和英文长度的问题
-
详解Vue中数组和对象更改后视图不刷新的问题
-
Javascript-Mozilla和IE中的一个函数直接量的问题分析_javascript技巧
-
Tensorflow 在c++上的编译和遇到的一些问题
-
C++中指针数组使用过程中的问题
-
Android解决ScrollView下嵌套ListView和GridView中内容显示不全的问题
-
关于js中类型转换的一些小问题
-
详解iOS开发中解析JSON中的boolean类型的数据遇到的问题
-
iOS中关于UIWindow和statusbar的设置问题
-
CSS Div 最小高度在IE 6 和IE 7中的兼容性问题