🍉内容专栏:【C/C++要打好基础啊】
🍉本文脉络:模板——函数模板——类模板
🍉本文作者:Melon西西
🍉发布时间 :2023.2.5
目录
(1)普通模板可以自动发生隐式类型转换,但是函数模板不可以。
一、函数模板:
模板:不能直接使用,可以提高复用性
建立一个通用函数,其函数返回值类型和形参类型可不具体指定,用一个虚拟的类型来代表。
语法:template<typename T> typename 也可以换成class
template——声明创建模板
typename——表面后面的符号是一种数据类型,可以用class代替
T——通用的数据类型,通常用T,可以替换
自动类型推导必须推导出一致的数据类型T才可以使用
模板必须要确定出T的数据类型才可以使用
1.1函数模板案例:
1.1.1.交换的函数模板:
比如完成交换要写好多类函数:
改成函数模板:模板有两种使用方法:
template<typename T> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型 void mySwap(T&a,T&b) { T temp =a; a=b; b=temp; } test1() { int a=10,b=20; swap(a,b); //或者可以这样写: mySwap<int>(a,b);//显示指定类型 }
1.1.2.排序函数模板
#include<iostream> using namespace std; template<typename T> void Swap(T& a, T& b) { T temp = a; a = b; b = temp; } template<typename T> //typename 也可以换成class void Sort(T arr[],int len) { for (int i = 0; i < len; i++) { int j = 0; int max = i; //设最大值的下边为i for (j = i + 1; j < len; j++) { if (arr[max] < arr[j]) max = j; } if (max != i) { Swap(arr[max], arr[i]); } } for (int i = 0; i < len; i++) { cout << arr[i] << " "; } } int main() { cout << "int类型数组排序" << endl; int arr1[] = { 8,5,2,3,9,1,4,6 }; int len1 = sizeof(arr1)/ sizeof(arr1[0]); Sort(arr1, len1); cout << endl; cout << "float类型数组排序" << endl; float arr2[] = { 4.1,7.3,5.6,2.8,6.3 }; int len2 = sizeof(arr2) / sizeof(arr1[0]); Sort(arr2, len2); return 0; }
1.2普通函数和函数模板的区别:(隐式类型转换)
(1)普通模板可以自动发生隐式类型转换,但是函数模板不可以。
隐式类型转换:结果是109,把字符型变量转化成整型变量进行了计算,c对应99,10+99=109;
int Add(int a,int b) { return a+b; } int main() { int a=10; char c='c'; cout<<Add(a,c)<<endl; }
(2)显式指定类型的情况可以用函数模板发生隐式类型转换
template<class T> int AddT(T a,T b) { return a+b; } int main() { int a=10; char c='c'; cout<<AddT<int>(a,c)<<endl;//结果也是109 }
(3)普通函数和函数模板的调用规则
①在普通函数和函数模板都可以实现的情况下,优先调用普通函数
②可以通过空模板参数列表来强制调用函数模板
③函数模板也可以发生重载
1.3模板的局限性:
模板的通用性不是万能的,比如:不能进行数组间的赋值操作,如果T是自定义数据类型,也不能进行比较。
有些特定数据类型,需要用具体化方式做特殊处理
二、类模板
建立一个通用类,类中的成员数据类型可以不具体确定,用一个虚拟的类型来表示
语法:template<typename T> template 可以用class代替
template<class NameType,class AgeType> class Person { public: NameType _Name; AgeType _Age; Person(NameType name,AgeType age) { this->_Name=name; this->_Age=age; } void Show() { cout<<"name:"<<this->_Name<<"age:"<<this->_Age<<endl; } }; int main() { Person<string,int> p1("橘橘",20); return 0; }