一、模板的引入
- 重载:函数名相同,参数列表不同——静多态(编译时期的多态)——早绑定
- C++中产生函数符号依赖于函数名和参数列表
- 假如能够把类型也当作参数传入函数中,可避免重载时大量重复代码的编写
二、函数模板
- 格式:
template<typename T> bool compare(T a,T b) { cout<<"template<typename T>bool compare(T a,T b)"<<endl; return a>b; }
- 传入的类型参数是在什么时候替换进去的,如何替换的?
- 模板不可以直接运行
- 模板会在编译期根据使用情况生成对应的函数指令
- 模板不编译,但模板生成的函数指令会编译,模板中的错误会在生成对应的指令时编译出错误
- 函数模板有类型自推的能力,使用函数模板可以不用传模板类型参数
int main() { compare<int>(10,20); compare(10.4,20.5);//自推为double型 return 0; }
-
函数模板的特例化:模板特例化优先级比普通模板高
//compare("aaa","bbb"); //如果调用普通的compare比较的是两个字符串地址,结果不可信 template<> bool compare(const char* a,const char* b) { cout<<"bool compare(const char* a,const char* b)"<<endl; return strcmp(a,b)>0;//比较ASCII码 }
- 优先级:普通函数 > 特例化模板 > 普通模板
三、类模板
- 格式:
//可以存放各种数据类型的模板类 template<typename T> class Arr { public: Arr(); Arr(const Arr& src); Arr& operator=(const Arr& src); ~Arr(); void push_back(const T& val); void pop_back(); T& back(); T& operator[](int pos); int size(); private: T* _arr; int _len; int _val_len; };
- 类模板不编译,会在编译期(针对的是单文件)根据使用方式生成对应的类代码(指令)
- 类模板中没有使用到的方法不会在编译期生成对应的指令
- 类模板使用时必须加上模板类型参数,类模板无法自己推导类型参数
- 类模板的成员方法只能在头文件或使用到的.cpp文件中实现,不能分开实现
- 为什么类模板的成员方法不能在其他.cpp文件中实现? 答:类模板需要在编译期将使用到的成员方法生成对应的指令,编译期是只针对单文件的, 如果将类模板的 成员方法实现在其他文件,编译期使用到该方法的文件不可见,就无 法生成对应的指令——报错:无法解析的外部符号