1.模板函数
1.1分为自动类型堆到和显示指定类型
template<class T>
void SwapNum(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
void test01()
{
int a = 10;
int b = 20;
double c = 30.5;
double d = 40.8;
SwapNum(a, b);//自动类型推导
SwapNum<int>(a, b);//显式指定类型
SwapNum(c, d);
cout << a << " " << b << " " << c << " " << d << endl;
}
2.注意事项
2.1自动类型推导必须推导出一致的类型T才可以使用
2.2模板必须要确定T的数据类型才可以使用
template<class T>
void SwapNum(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
template<class T>
void func()
{
cout << "函数func的调用" << endl;
}
void test01()
{
int a = 10;
int b = 20;
char c = 'c';
SwapNum(a, b);//正确,可以推导出一致的类型数据
//SwapNum(a, c);错误,推导不出一致的类型数据
}
void test02()
{
//func();//不能直接调用函数模板
func<int>();//要指定函数模板的参数才能调用
}
//函数模板案例——数组排序的函数模板
template<class T>
void SwapNum(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
template<class T>//排序数组的函数模板
void Sort(T arr[],int len)//选择排序
{
for (int i = 0; i < len; i++)
{
int min = i;
for (int j = i + 1; j < len; j++)
{
if (arr[j] < arr[min])
{
min = j;
}
}
if (i != min)
{
SwapNum(arr[i], arr[min]);
}
}
}
template<class T>//打印数组的函数模板
void Print_Arr(T arr[], int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void test01()
{
char arr1[] = "cabeidfgjh";
int len = sizeof(arr1) / sizeof(char);
Sort(arr1, len);
Print_Arr(arr1, len);
}
void test02()
{
int arr2[] = { 3,5,2,4,6,1,8,7,9 };
int len = sizeof(arr2) / sizeof(int);
Sort(arr2, len);
Print_Arr(arr2, len);
}
3.普通函数与函数模板的区别
3.1普通函数调用时可以发生自动类型转换(隐式类型转换)
3.2函数模板在使用自动类型推导方式时,不会发生自动类型转换
3.3函数模板使用显示指定类型方式时,可以发生隐式类型转换
使用过程中建议使用显示指定类型方式,方便自己确定通用类型
int AddNum1(int a, int b)//普通函数
{
return a + b;
}
template<class T>//函数模板
T AddNum2(T a, T b)
{
return a + b;
}
void test01()
{
int a = 10;
int b = 20;
char c = 'a';
cout << AddNum1(a, c) << endl;//普通函数的隐式转换,a转为ASCII码值为97
//cout << AddNum2(a, c) << endl;//自动推导型不能发生隐式转换
cout << AddNum2<int>(a, c) << endl;//函数模板的指定类型方式可以
}
4.普通函数和函数模板的调用规则
4.1如果普通函数和模板函数都可以实现,优先使用普通函数(即使普通函数没有实现代码)
4.2可以通过空模板参数列表来强制调用函数模板
4.3函数模板也可以发生重载
4.4如果函数模板可以产生更好的匹配,优先调用函数模板
一般写了函数模板就不会再写普通函数,容易产生二义性
void Print(int a,int b)//普通函数
{
cout << "调用的普通函数" << endl;
}
template<class T>//函数模板
void Print(T a,T b)
{
cout << "调用的函数模板" << endl;
}
void test01()
{
int a = 10;
int b = 20;
Print(a, b);//都可以实现,优先调用普通函数
Print<>(a, b);//可以通过空模板参数列表来强制调用函数模板
char c = 'c';
char d = 'd';
Print(c,d);//如果函数模板可以产生更好的匹配,优先调用函数模板
}
5.模板的局限性
template<class T>
void func(T& a, T& b)
{
a = b;//如果传入的是数组,就无法实现赋值操作
}
template<class T>
bool Compare(T &a, T &b)//如果传入的是自定义类型就无法比较了
{
if (a == b)
{
return true;
}
else
{
return false;
}
}
5.1利用具体化的模板,可以解决自定义类型的通用化
5.2学习模板不是为了自己写模板,而是为了在STL中使用系统提供的模板
class Person
{
public:
Person(string name,int age)
{
this->m_name = name;
this->m_age = age;
}
string m_name;
int m_age;
};
template<class T>
bool Compare(T &a, T &b)//比较不了自定义类型
{
if (a == b)
{
return true;
}
else
{
return false;
}
}
template<>bool Compare(Person& a, Person& b)//利用具体化的Person的版本实现代码,具体化优先调用
{
if (a.m_name == b.m_name && a.m_age == b.m_age)
{
return true;
}
else
{
return false;
}
}
void test01()
{
int a = 10;
int b = 10;
if (Compare(a, b))
{
cout << "a==b" << endl;
}
else
{
cout << "a!=b" << endl;
}
Person p1("Tom", 10);
Person p2("Tom", 10);
if (Compare(p1, p2))
{
cout << "p1==p2" << endl;
}
else
{
cout << "p1!=p2" << endl;
}
}
标签:调用,return,函数,int,void,语法,template,模板
From: https://blog.csdn.net/weixin_74207910/article/details/140436736