hello~ 很高兴见到大家! 这次带来的是C++中关于模板这部分的一些知识点,如果对你有所帮助的话,可否留下你的三连呢? 个 人 主 页: 默|笙

泛型编程:泛型编程是一种编程范式,它允许在定义函数、类或数据结构时使用类型参数,这些参数可以在使用时被具体类型替换。泛型编程的核心目标是编写通用、可复用的代码,同时保持类型安全。
例如对整形之间、浮点型之间以及字符之间实现交换操作的交换函数:
void Swap(int& n1, int& n2)//对整数
{
int tmp = n1;
n1 = n2;
n2 = tmp;
}
void Swap(double& n1, double& n2)//对浮点数
{
double tmp = n1;
n1 = n2;
n2 = tmp;
}
void Swap(char& n1, char& n2)//对字符
{
char tmp = n1;
n1 = n2;
n2 = tmp;
}函数重载的本质是为不同类型创建多个独立的同名函数,这只是语法层面的 “复用”,而非真正的代码复用。我们仍需写重复冗余代码,且维护成本极高(如修改逻辑时需要同步修改所有重载函数)。
我们从泛型编程那里可以了解到:模板是实现泛型编程的基础,是实现它的具体语法工具。接下来让我们走进模板:
就像是做石膏娃娃的模具:

倒入白色的膏体出现的自然是白色的石膏娃娃,同样,如果导入的是其他颜色的膏体出现的自然是不同颜色的石膏娃娃,它们相像但并不相同。
函数模板代表了一个函数家族,该函数模板与具体类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
//模板参数声明:
template<typename T1, typename T2, typename T3,......,typename Tn>
返回类型 函数名(参数列表) {
// 函数体,使用 T1,T2 等作为类型
}typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)。
像是之前交换函数的代码,就可以这样写:
template<typename T>
void Swap(T& n1, T& n2)
{
T tmp = n1;
n1 = n2;
n2 = tmp;
}
函数模板的实例化是指编译器根据模板定义和实际调用时的类型参数,生成具体函数代码的过程。它分为隐式实例化和显式实例化。
由编译器根据传入实参对推演模板参数的具体类型。
我们来看接下来的一段错误代码:
template<typename T>
T Add(T& n1, T& n2)
{
return n1 + n2;
}
int main()
{
int n1 = 1;
float n2 = 2.2f;
cout << Add(n1, n2) << endl;
return 0;
}发生报错的原因:
修改方法:
template<typename T, typename U>//增加模板参数,让 int 和 float 都能匹配上
T Add(T& n1, U& n2)
{
return n1 + n2;
}
int main()
{
int n1 = 1;
float n2 = 2.2f;
// 自动推导:T=int, U=float
cout << Add(n1, n2) << endl;
return 0;
}template<typename T>
T Add(const T& n1, const T& n2)//加上const用来修饰,如此可绑定临时变量
{
return n1 + n2;
}
int main()
{
int n1 = 1;
float n2 = 2.2f;
// 自动推导:T=int, U=float
cout << Add(n1, (int)n2) << endl;//强制转换为 int 类型,形成临时变量
return 0;
}由我们用户主动在函数名后的<>中指定模板参数的实际类型。
template<typename T>
T Add(const T& n1, const T& n2)
{
return n1 + n2;
}
int main()
{
int n1 = 1;
float n2 = 2.2f;
// 自动推导:T=int, U=float
cout << Add<int>(n1, n2) << endl;
return 0;
}//int类型加法函数
int Add(int n1, int n2)
{
cout << "int Add(int n1, int n2)" << endl;
return n1 + n2;
}
//模板加法函数
template<typename T, typename U>
T Add(T n1, U n2)
{
cout << "T Add(T n1, U n2)" << endl;
return n1 + n2;
}
int main()
{
Add(1, 2);//实参完全与非模板函数匹配,不会从模板函数里产出一个实例
Add(1, 2.2);//第二个实参需要进行隐式转换才能匹配上非模板函数,
//而模板函数能够产出一个匹配度更高的函数,选择模板函数的实例化版本
return 0;
}
template<typename T1, typename T2, ..., typename Tn>
class 类模板名
{
// 类内成员定义,可以使用T1,T2,...,Tn作为类型
};类模板实例化必须显式实例化,在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。
template<typename T>
class Stack { /* ... */ };
//对于实例化:Stack只是类模板名,Stack<int>才是具体的类型名
Stack<int> intStack; // 显式实例化为 int类型的 Stack今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~ 如果可以, 那就让我们共同努力, 一起走下去!