#include<iostream>
using namespace std;//函数模块//两个整数交换voidswapInt(int&a ,int&b){int t = a;
a = b;
b = t;}//两个浮点数交换voidswapDoub(double&a ,double&b){double t = a;
a = b;
b = t;}//函数模块
template<typename T>//声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个 通用数据类型voidmySwap(T &a , T &b){
T t = a;
a = b;
b = t;}intmain(){int a =10;int b =20;// swapInt(a , b);//两种方式使用函数模板//1、自动类型推导//mySwap(a , b);//2、显示指定类型
mySwap<int>(a,b);
cout <<"a = "<< a << endl;
cout <<"b = "<< b << endl;/* double c = 1.1;
double d = 2.2;
swapDoub(c , d);
cout << "c = " << c << endl;
cout << "d = " << d << endl;*/return0;}
1.1.2、函数模板注意事项
#include<iostream>
using namespace std;//函数模板注意事项
template<class T>//typename 可以替换成 classvoidmySwap(T &a , T &b){
T temp = a;
a = b;
b = temp;}//1、自动类型推导,必须推导出一致的数据类型 T 才可以使用voidtest01(){int a =10;int b =20;char c='a';// mySwap(a , b); //正确//mySwap(a ,c); //错误 ,推导不出一致的 T 类型
cout <<"a = "<< a << endl;
cout <<"b = "<< b << endl;}//2、模板必须要确定出 T 的数据类型,才可以使用
template<class T>voidfunc(){
cout <<"func 函数调用"<< endl;}voidtest02(){
func<int>();}intmain(){test01();return0;}
1.1.3、函数模板案例–数组排序
#include<iostream>
using namespace std;//实现通用 对数组进行排序的函数//规则 从大到小//算法 选择//测试char 数组 、int 数组//交换函数模板
template<class T>voidmySwap(T &a , T &b){
T temp = a;
a = b;
b = temp;}//排序算法
template<class T>voidmySort(T arr[],int len){for(int i =0; i < len ; i++){int max = i;for(int j = i +1; j < len ; j++){if(arr[max]< arr[j]){
max = j;}}//交换max和i元素if(max != i){mySwap(arr[max], arr[i]);}}}//打印数组模板
template<class T>voidprintArray(T arr[],int len){for(int i =0; i < len ; i++){
cout << arr[i]<<" ";}
cout << endl;}voidtest01(){//测试char数组char charArr[]="badcfe";int num =sizeof(charArr)/sizeof(char);mySort(charArr , num);printArray(charArr,num);}voidtest02(){//测试int数组int intArr[]={2,4,6,1,5,9};int len =sizeof(intArr)/sizeof(int);mySort(intArr , len);printArray(intArr , len);}intmain(){//test01();test02();return0;}
1.1.4、普通函数与函数模板的区别
#include<iostream>
using namespace std;//普通函数与模板函数区别//1、普通函数调用可以发生隐式类型转换//2、函数模板 用自动类型推导,不可以发生隐式类型转换//3、函数模板 用显示指定类型,可以发生隐式类型转换//普通函数intmyAdd01(int a,int b){return a + b;}//函数模板
template<class T>intmyAdd02(T a , T b){return a + b;}voidtest01(){int a =10;int b =20;char c ='c';// ASCll码 99
cout <<myAdd01(a , c)<< endl;//自动类型推导,不可以发生隐式类型转换//cout << myAdd02(a ,c) << endl;//显示指定类型,可以发生隐式类型转换
cout << myAdd02<int>(a , c)<< endl;}intmain(){test01();return0;}
1.1.5、普通函数与函数模板调用规则
#include<iostream>
using namespace std;//普通函数与模板函数调用规则//1、如果函数模板和普通函数都可以调用,优先调用普通函数//2、可以通过空模板参数列表,强制调用,函数模板//3、函数模板可以发生函数重载//4、如果函数模板可以产生更好的匹配,优先调用函数模板voidmyPrint(int a ,int b){
cout <<"调用普通函数"<< endl;}
template<class T>voidmyPrint(T a , T b){
cout <<"调用模板"<< endl;}
template<class T>voidmyPrint(T a , T b, T c){
cout <<"调用重载模板"<< endl;}voidtest01(){int a =10;int b =20;// myPrint(a, b); //调用普通函数//通过空模板参数列表,强制调用函数模板//myPrint<>(a,b);//myPrint(a,b,100); //模板重载char c1 ='a';char c2 ='b';//如果函数模板可以产生更好的匹配,优先调用函数模板//因为不用强制转,所以会优先用函数模板myPrint(c1 , c2);}intmain(){test01();return0;}
1.1.6、模板的局限性
模板的通用性并不是万能的
#include<iostream>
using namespace std;//模板局限性//模板并不是万能的,有些特定数据类型,需要用具体方式做特殊实现
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 myCompare(T &a , T &b){if(a == b){return true;}else{return false;}}//利用具体化Person的版本实现代码,具体化优先调用
template<> bool myCompare(Person &p1 , Person &p2){if(p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age){return true;}else{return false;}}voidtest01(){int a =10;int b =10;
bool ret =myCompare(a , b);if(ret){
cout <<"a == b"<< endl;}else{
cout <<"a != b"<< endl;}}voidtest02(){
Person p1("LI",20);
Person p2("LI",20);
bool ret =myCompare(p1 , p2);if(ret){
cout <<"p1 == p2"<< endl;}else{
cout <<"p1 != p2"<< endl;}}intmain(){//test01();test02();return0;}
1、模板1.1、函数模板1.1.1、函数模板语法#include <iostream>using namespace std;//函数模块//两个整数交换void swapInt(int &a , int &b){ int t = a; a = b; b = t;}//两个浮点数交换void swapDoub(double &a , double &b){ double t = a; a = b