模板:顾名思义,它是一个通用框架,可以根据不同数据类型生成不同的版本代码,减少代码的书写量(简洁规范)
模板有两种特殊实现:
实例化;
1.实例化分隐式实例化和显示实例化
2. 显示实例化的目的是人工优化编译效率(在明确知道模板的转换类型的
情况下,可以实例化模板)
// 函数模板实例化
template <typename T>
inline T max (T a, T b)
{
return a < b ? b : a;
}
template int max<int>(int a, int b); //显式实例化,指定编译器生成int类型的模板定义
template int max<>(int a, int b); //简写
template int max(int a, int b); //简写
int max(int a, int b); //甚至,其实就是普通函数
// 类模板实例化
template<class T>
struct Z // 模板定义
{
void f() {}
void g(); // 不会被定义
};
template struct Z<double>; // 显示实例化 Z<double>
Z<int> a; // 隐式实例化 Z<int>
Z<char>* p; // 无任何实例化生成
p->f(); // 隐式实例化 Z<char> and Z<char>::f().
// Z<char>::g() 不会被声明和定义
具体化/特化(全特化和部分特化/偏特化);
1. 特化的意义在于可以为一个或多个特殊类型提供特殊的处理(即原始模板逻辑无
法满足特殊类型需求,需要单独处理的情况,类似函数重载)。
2.函数模板只能全特化(因为函数模板可以重载的原因)
tps:函数模板不能偏特化的原因主要是因为函数模板本身支持重载机制,这已经足够满足不同类型参数的需求。在C++中,函数模板可以通过重载来实现类似偏特化的效果,而不需要引入偏特化的概念。
// ---------- 模板函数 ---------------------------------
template<typename T1, typename T2>
void fun(T1 a , T2 b)
{
cout<<"模板函数"<<endl;
}
//全特化
template<>
void fun<int ,char >(int a, char b)
{
cout<<"全特化"<<endl;
}
//函数不存在偏特化:下面的代码是错误的 ,
// 由于函数模板可以重载,编译器默认把下面的fun函数模板当成模板重载,
// 这个函数模板只有一个形参T2,但是fun<>里标注了两个参数char、T2,编译器报错。
/*
template<typename T2>
void fun<char,T2>(char a, T2 b)
{
cout<<"偏特化"<<endl;
}
*/
//所以上面可以改成模板重载的形式
template<typename T2>
void fun(char a, T2 b)
{
cout<<"函数模板重载"<<endl;
}
// -------------- 类模板 -------------------------------------
template<typename T1, typename T2>
class Test
{
public:
Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"<<endl;}
private:
T1 a;
T2 b;
};
template<>
class Test<int , char>
{
public:
Test(int i, char j):a(i),b(j){cout<<"全特化"<<endl;}
private:
int a;
char b;
};
template <typename T2>
class Test<char, T2>
{
public:
Test(char i, T2 j):a(i),b(j){cout<<"偏特化"<<endl;}
private:
char a;
T2 b;
};
重载;
函数才能重载,重载和特化有点类似,重载在于参数类型和数量的区别,
模板的参数类型为泛型,所以只能改变参数数量实现重载
template <typename T>
inline T const& max(T const& a, T const& b) {
printf("原函数调用.\n");
return a < b ? b : a;
}
// 重载
template <typename T>
inline T const& max(T const& a, T const& b, T const& c) {
printf("重载1调用.\n");
return ::max(::max(a,b),c);
}
template <typename T>
inline T const& max(T const& a, T const& b, int const& c) {
printf("重载2调用.\n");
return ::max(::max(a,b),c);
}
注意:
虽然模板配重载也可以达到同样的效果,但特化版的意图更加明确。
借阅:
https://blog.youkuaiyun.com/qq_60755751/article/details/134984138
https://blog.youkuaiyun.com/weixin_34072637/article/details/93787818