学习:模板

函数模板:

C++另一种编程思想称为泛型编程,主要利用的技术就是模板

C++提供两种模板机制:函数模板类模板


函数模板语法:

函数模板作用:

建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。

语法:

template<typename T>

函数声明或定义

解释:

template --- 声明创建模板

typename --- 表面其后面的符号是一种数据类型,可以用class代替

T --- 通用的数据类型,名称可以替换,通常为大写字母

示例代码:

#include<iostream>
using namespace std;
template<typename T>
void mySwap(T& a, T& b) //利用传递的方式
{
T temp = a;
a = b;
b = temp;
}
void test01() {
//有两种种调用方式
int a = 10;
int b = 20;
//第一种自动类型推导
mySwap(a, b);
//第二种调用方式
mySwap<int>(a, b); //显示指定类型
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
int main() {
test01();
system("pause");
return 0;
}

总结:
1、函数模板利用关键字 template
2、使用函数模板有两种方式:自动类型推导显示指定类型
3、模板的目的是为了提高复用性,将类型参数化


函数模板注意事项:

1、自动类型推导,必须推导出一致的数据类型T,才可以使用

示例代码:

#include<iostream>
using namespace std;
template<typename T>
void Swap(T &a, T &b) {
T temp;
temp = a;
a = b;
b = temp;
}
void test01() {
int a = 10;
int b = 20;
int c = 0.1;
//Swap(a,b); //正确
Swap(a, c);//错误
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
int main() {
test01();
system("pause");
return 0;
}

2、模板必须要确定出T的数据类型,才可以使用
示例代码:

#include<iostream>
using namespace std;
template<typename T>
void func() {
cout << "this is test" << endl;
}
void test01() {
// func(); 直接调用无法运行,我们必须要指定类型
func<int>();
}
int main() {
test01();
system("pause");
return 0;
}

普通函数与函数模板区别:

大家记住三句话就可以了

1、普通函数调用时可以发生自动类型转换(隐式类型转换)
2、函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
3、如果利用显示指定类型的方式,可以发生隐式类型转换

#include<iostream>
using namespace std;
template<class T>
int test01(T a, T b) {
return a + b;
}
int test02(int a,int b) {
return a + b;
}
int main() {
cout << test02(1, 2) << endl; //可以打印
cout << test02(1, 'a') << endl;//可打印
cout << test01(1, 2) << endl; //可以打印
cout << test01('a','a') << endl; //可以打印
//cout << test01(1, 'a') << endl; //不可以打印
cout << test01<int>(1, 'a') << endl; //可以打印
system("pause");
return 0;
}

普通函数与函数模板的调用规则:

#include<iostream>
using namespace std;
void test01(int a,int b) {
cout << "这是调用了普通函数" << endl;
}
template<class T>
void test01(T a, T b) {
cout << "这是调用了函数模板" << endl;
}
template<class T>
void test01(T a, T b, T c) {
cout << "这是调用了重载函数模板" << endl;
}
int main() {
test01(1, 1); //优先调用普通函数
test01<>(1, 1); //可以利用空模板的方式进行优先调用函数模板
test01(1, 2, 3); //函数模板可以进行重载
test01('a', 'b'); //函数模板如果可以产生更好的匹配,那么会优先调用函数模板
system("pause");
return 0;
}

总结:既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性


模板的具体化:

具体化的特点
1、具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
2、具体化优先于常规模板

作用:当我们一个比较数值的函数模板,如果传入单个数值比较的话是可以的,但是如果我们传入的数值是一个数组,一个类的话那么就无法进行比较,C++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板

示例代码:

#include<iostream>
#include<string>
using namespace std;
class Person {
public:
Person(string name,int age) {
this->m_age = age;
this->m_name = name;
}
public:
int m_age;
string m_name;
};
template<class T>
bool Compare(T a, T b) {
if (a == b) {
return true;
}else {
return false;
}
}
//具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
//具体化优先于常规模板
template<> bool Compare(Person a, Person b) { //template<> 这种写法对Compare的函数模板进行模板具体化 传入的参数为Person,这里传入引用不引用其实都没关系,只是进行比较
if (a.m_age == b.m_age) {
return true;
}else {
return false;
}
}
int main() {
//int a = 1;
//int b = 2;
bool ret;
//ret = f1(a, b);
Person p1("adexx", 18);
Person p2("adedd", 19);
ret = Compare(p1, p2);
if (ret) {
cout << "true" << endl;
}else {
cout << "false" << endl;
}
system("pause");
return 0;
}
posted @   zpchcbd  阅读(188)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示