#include <iostream> //1.1函数模板 //int 数据交换 using namespace std; void myswap(int& a,int &b) { int temp=a; a=b; b=temp; } //double类型数据交换 void myswap(double &a, double &b) { double temp=a; a=b; b=temp; } //模板技术 类型参数化 编写代码可以忽略类型 //为了让编译器是普通函数,还是模板函数 //template <class T> template <typename T>//告诉编译器,下面写模板函数,且只对后面第一个函数有效 void Myswap(T &a,T& b) { T temp=a; a=b; b=temp; } void test1() { int a=11; int b=13; double a1=1.23; double b1=2.25; //1.l自动类型推导 cout<<"a:"<<a<<"b:"<<b<<endl; Myswap(a,b);//编译器根据你传入的值,进行类型的自动推导,去替换相应的值。 cout<<"a:"<<a<<"b:"<<b<<endl; cout<<"a1:"<<a1<<"b1:"<<b1<<endl; Myswap(a1,b1); cout<<"a1:"<<a1<<"b1:"<<b1<<endl; //2.显示的指定类型 cout<<"---------------------------"<<endl; cout<<"a:"<<a<<"b:"<<b<<endl; Myswap<int>(a,b); cout<<"a:"<<a<<"b:"<<b<<endl; cout<<"a1:"<<a1<<"b1:"<<b1<<endl; Myswap<double >(a1,b1); cout<<"a1:"<<a1<<"b1:"<<b1<<endl; } //2函数模板和普通函数的区别 //1.函数模板不允许自动类型转化 //2.普通函数能够自动进行类型转化 template <class type> int myadd(type a,type b)//模板函数 { cout<<"模板函数.............."<<endl; return a+b; } int myadd(int a,char c) { cout<<"普通函数..................."<<endl; return a+c;//编译器会把c做自动类型转换 } void test2() { int a=10; int b=11; char c1='a'; char c2='b'; myadd(a,c1);//调用普通函数 myadd(a,b);//调用模板函数,模板函数必须严格类型匹配 myadd(c1,b);//,调用的普通函数,普通函数可以进行自动类型转换 } //3.函数模板和普通函数调用的规则 //3.1.函数模板可以像普通函数那样被重载 //3.2.c++编译器优先考虑普通函数(当模板函数和普通函数都能匹配的时候,编译器优先调用普通函数) //3.3如果函数模板可以产生一个更好的匹配,那么选择模板 //3.4可以通过空模板实参列表的语法限定编译器只能通过模板匹配 //3.1函数模板可以被重载 template <class T> void print(T a) { } template <class T> void print(T a,T b) { } //c++编译器模板机制剖析 //.cpp->预编译器(生成.i文件)->编译器(生成.s文件,汇编文件)->汇编器(生成.obj,.o文件)->链接器(生成可执行文件.exe) //函数模板实现原理剖析 //函数模板->模板函数(编译器根据传入的参数写出模板函数)->被调用。 //函数模板机制结论: //1.编译器并不是把函数模板处理成能够处理任何类型的函数 //2.函数模板通过具体类型产生不同的函数 //3.编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译 int main() { //test1(); test2(); return 0;
}