一 概念
- 在C++中,模板特化是一种机制,允许你为特定类型的模板参数提供专门的实现,主要分为全特化和偏特化
- 编译器认为、对于特定的类型,如果你能对某一功能更好的实现,那么就应该听你的。
- 说白了就是对特定的类型进行特定的代码编写(私人定制)
二 全特化
- 全特化是指为模板的所有模板参数提供一个具体的实现。换句话说,就是为特定的一组类型参数提供一个完全不同的实现。
- 简单来说:就是将所以模板参数全部指定为确定类型
2.1 类的全特化
2.1.1 全特化前提(原始类模板)
- 首先我们在全特化前必须定义一个原始模板类,并且全特化的模板类必须与之定义相匹配
template <typename T1,typename T2>
class templateA
{
public:
void printer()
{
qDebug()<<"templateA 原始类模板";
}
};
2.1.2 全特化类模板
- 这里实现两个全特化类<int,float>和<float,float>
- 这两个类完全可以有自己不同的实现
emplate <>
class templateA<int,float>
{
public:
void printer()
{
qDebug()<<"<int,float> 类全特化";
}
};
template <>
class templateA<float,float>
{
public:
void printer()
{
qDebug()<<"<float,float> 类全特化";
}
void show()
{
qDebug()<<"<float,float> 类全特化";
}
};
2.2 qt中的全特化例子
- 我们稍微更改一下qt中gloab.h中的源码
template <int> class QIntegerForSize;
template <> class QIntegerForSize<1> {public: typedef quint8 Unsigned; typedef qint8 Signed; };
template <> class QIntegerForSize<2> {public: typedef quint16 Unsigned; typedef qint16 Signed; };
template <> class QIntegerForSize<4> {public: typedef quint32 Unsigned; typedef qint32 Signed; };
template <> class QIntegerForSize<8> {public: typedef quint64 Unsigned; typedef qint64 Signed; };
- 在这部分定义中,我们首先定义了一个普通的模板类
template<int> class QInterForSize;
- 接下来使用template<> 进行全特化
- 全特化的结构与主模板无需一致这就叫私人定制
template <>
class QIntegerForSize<1>
{
public:
typedef quint8 Unsigned;
typedef qint8 Signed;
};
2.2 函数全特化
- 同样的我们也需要定义一个原始函数模板
template <typename T1,typename T2>
void showAAA(T1 ,T2)
{
qDebug()<<"函数模板";
}
template <>
void showAAA(int *a,int b)
{
*a = b;
qDebug()<<"函数特化";
}
- 然后我们使用函数的特化
- 在这个函数特化中我们将第二个int传给了第一个int的值。
int *funcTemp = new int;
showAAA(funcTemp,10);
qDebug()<<"funcTemp = "<<*funcTemp;
三 偏特化
- 偏特化:偏特化是指为模板的部分模板参数提供一个具体的实现。也就是说,你只需要为部分模板参数提供一个特化的实现,而其他的模板参数仍然保留通用的实现。
3.1 类的偏特化
- 同样的我们需要在偏特化前定义一个原始类模板
- 之后再定义偏特化的类模板
template <typename T1,typename T2>
class templateA
{
public:
void debug()
{
qDebug()<<"偏特化原始类模板";
}
};
template <typename T1>
class templateA<T1,float>
{
public:
void debug()
{
qDebug()<<"类的偏特化";
}
};
templateA<int,float> template_A;
template_A.debug();
3.2 函数不能偏特化
- 模板函数不能偏特化
- 我们写了下面这样一个想要实现它的偏特化,但最终会发现,它会一直调用原始函数模板。
template <typename T1,typename T2>
void debug(T1 a,T2 b)
{
qDebug()<<a<<"偏特化原始函数模板"<<b;
}
template <typename T1>
void debug(int a,double b)
{
qDebug()<<a<<"函数的偏特化"<<b;
}
debug<int,double>(10,10.009);
四 类特化的标志
- 当某个类后面跟了<> 那么表示这个类是被特化了。