模板之函数模板
宏替换:不做类型检查。
重载:为每个类型提供一个重载版本。
模板:提供一个模板,为相同逻辑功能提供一个模板。将类型当作参数来传递,让编译器实例化对应函数来处理。不同的版本由编译器维护。(静态多态)
模板是一种参数化的多态工具,所谓参数化的多态性,是指将程序所处理的对象的类型参数化,使一段程序代码可以用于处理多种不同类型的对象。采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享机制。
模板分类:函数模板、类模板。
函数模板的说明
template<模板形参表> 返回值类型 函数名(模板函数形参表){
//函数定义体
}
函数模板的定义以关键字template开头
Template之后<>中是函数模板的参数列表
函数模板的参数是类型参数,其类型为class或者typename
template<class T> / template<class T1,class T2>
模板形参在模板中作为一种类型使用,可以用于函数的形参、函数返回值和函数的局部变量
每个模板形参要在函数的形参列表中至少出现一次
模板参数名的作用域局限于函数模板范围内。
函数模板的使用:
函数模板为所有的函数提供唯一的一段函数代码,增强了函数设计的通用性。
使用函数模板的方法是,先说明函数模板,然后实例化成相应的模板函数进行调用执行。
1、 函数模板不是函数,不能被执行。
2、 置换代码中的类型参数得到函数模板——实例化。
3、 实例化后的模板函数是真正的函数,可以被执行。
函数模板的使用:模板被编译了两次
实例化之前,先检查模板代码本身,查看语法是否正确。在这里会发现语法错误
实例化期间,检查模板代码,查看是否所有的调用都有效。在这里会发现无效的调用,如该实例化类型不支持某些函数调用等。
普通函数只需要声明,即可顺利编译,而模板的编译需要查看模板的定义
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 template<typename T> 5 const T& max(const T& a,const T& b) 6 { 7 return a < b ? b : a; 8 } 9 //函数模板特化,本质上还是属于模板函数 10 template<> 11 const char* const& max(const char* const& a,const char* const& b) 12 { 13 return strcmp(a, b) < 0 ? b : a; 14 } 15 //函数模板重载 16 template <typename T> 17 const T& max(const T& a,const T& b,const T& c) 18 { 19 return ::max(a, b) < c ? c : max(a, b); 20 } 21 //非模板函数进行重载,先找全局函数然后才找模板函数,除非显示指定要用模板函数 22 const int& max(const int& a,const int& b) 23 { 24 return a < b ? b : a; 25 } 26 int main(void) 27 { 28 cout << ::max(5.5, 6.6) << endl;//实例化出模板函数 29 cout << ::max('a','b') << endl;//自动推导 30 string str1 = "aaa"; 31 string str2 = "bbb"; 32 cout << ::max(str1,str2) << endl; 33 cout << ::max(1,5,3) << endl; 34 cout << ::max<>(97, 100) << endl;//模板自动推导 35 cout << ::max<int>(97, 100) << endl;//显示指定模板函数,不是自动推导 36 return 0; 37 }