(1)为啥要函数模板特化
在C++中主要是为了解决“一刀切”的问题,当我们定义一个模板(无论是函数模板还是类模板)时,它旨在为多种类型提供通用的解决方案。然而,在实际应用中,有些类型可能并不适合这种通用的处理方式,或者我们可以为这些类型提供更加高效、更加符合直觉的实现方式。
模板特化就是针对这种情况提供的一种解决方案。它允许我们为特定的类型或类型组合提供定制化的实现,而不影响其他类型的通用实现。这样,我们就可以在保持模板灵活性和通用性的同时,针对特定情况进行优化或定制。
简单来说,模板特化就是“为特定的类型或情况提供定制化的模板实现”。这样做可以提高代码的效率、可读性和可维护性。
(2)特化的分类及使用方法
特化可以针对特定的类型或值来提供给特定的函数实现。模版的特化分为:全特化(fully specialized)或部分特化(partially specialized)。其中部分特化的本质是对参数的进一步限制
但请注意
1.函数模板不支持部分特化,只能进行全特化。
2.特化是不能单独存在的,需要原来的模版
3.部分特化和全特化重叠时,会用全特化,也就是说编译器会找最匹配的
(1)全特化示例使用方法(红色部分)
template <typename T>
void print(T value)
{
std::cout << "General print: " << value << std::endl;
}
------------------------上面的代码是原模版-----------------------------------
// 特化print函数模板以处理int类型
template <>
void print<int>(int value)
{
std::cout << "Specialized print for int: " << value << std::endl;
}
int main()
{
print(10); // 调用特化的版本
print(3.14); // 调用通用版本
return 0;
}
————————————————————————————————————
(2)部分特化示例使用方法(红色部分)
// 假设我们有一个模板对,我们想对第一个类型为int的情况进行特化
template <typename T1, typename T2>
class Pair
{
public: void show()
{
std::cout << "General Pair" << std::endl;
}
};
------------------------上面的代码是原模版-----------------------------------
// 部分特化,其中T1为int
template <typename T2>
class Pair<int, T2>
{
public: void show()
{
std::cout << "Specialized Pair where first type is int" << std::endl;
}
};
int main()
{
Pair<int, double> intDoublePair;
intDoublePair.show();
// 调用部分特化的版本
Pair<double, float> doubleFloatPair;
// 调用通用版本
doubleFloatPair.show();
return 0;
}
(3)模版分离编译
在C++中,模版分离通常指的是将类模板或函数模版的声明和定义放在不同的文件中,以提高代码的可读性和可维护性。然而,由于模板的特殊性(编译器需要在实例化模板时看到模板的定义),直接分离声明和定义到不同的文件可能会导致编译错误。
如何避免分离编译时出的错误呢?下面我们用一个简单的方式看待问题,把声明看做是定金,把定义看做是现金,把编译器看做是卖房子的人。
1.将模板的声明和定义都放在头文件中
当要买房子的时候,我们有钱的情况下,先给一部分定金签合同,再给后边的尾款,合同生效交易完成,同理,当需要用到这个模版的时候,头文件直接包含这个模版的声明和定义就相当于自己有钱了,包含头文件,编译器根据需求,直接把地址给需要用到的地方,这个就相当于交易完成。
示例代码如下:
MyTpClass.h(声明和定义)
#ifndef MYTPCLASS_H
#define MYTPCLASS_H
//声明
template <typename T>
class MyTpClass
{
public:
void doTest(T param);
};
//定义
template <typename T>
void MyTpClass<T>::doTest(T param)
{
// 实现
}
#endif
2.显示实例化
显示实例化是 明确告诉编译器 需要为模板的特定类型生成代码实例 的过程。这个就相当于,你要买个30w的房子,全款你的钱不够,你先给个3万定金(头文件里写声明),然后你找兄弟借27万现金(.cpp写了模版定义,定义就看做现金 ),然后所有钱加在一起给卖房子的人(编译器)。
示例代码如下:
MyTpClass.h(声明)
#ifndef MYTPCLASS_H
#define MYTPCLASS_H
//声明
template <typename T>
class MyTpClass
{
public:
void doTest(T param);
};
#endif
MyTpClass.cpp(定义和显示实例化)
#include "MyTpClass.h"
//定义
template <typename T>
void MyTpClass<T>::doTest(T param)
{
// 实现
}
// 显示实例化 MyTpClass模板的int和float类型
template
class MyTpClass<int>;
template
class MyTpClass<float>;