【C++】模板初阶 末蓝、 2024-03-26 17:17 98阅读 0赞 #### 文章目录 #### * 模板初阶 * * 1. 泛型编程 * 2. 函数模板 * * 2.1 函数模板概念 * 2.2 函数模板格式 * 2.3 函数模板的原理 * 2.4 函数模板的实例化 * 2.5 模板参数的匹配原则 * 3. 类模板 * * 3.1 类模板的定义格式 * 3.2 类模板的实例化 ## 模板初阶 ## ### 1. 泛型编程 ### 如何实现一个交换函数,我们可以的使用场景: void Swap(int& left, int& right) { int temp = left; left = right; right = temp; } void Swap(double& left, double& right) { double temp = left; left = right; right = left; } void Swap(char& left, char& right) { char temp = left; left = right; right = temp; } .............. 使用函数重载虽然可以实现,但是有以下几个不好的地方: 1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数 2. 代码的维护性比较低,一个出错可能所有的重载都出错 **我们可以告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码** 如果在C++当中,有这样一个模具,通过这样的模具**填充不同的材料(类型)**,来获得不同材料的铸件(即生成具体类型的代码),那将会节省许多头发。巧的前人早已栽好树,我们只需要乘凉就行 **泛型编程**:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础 ### 2. 函数模板 ### #### 2.1 函数模板概念 #### > 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本 #### 2.2 函数模板格式 #### `template<typename T1, typename T2....>` 返回值类型 函数名(参数列表)\{\} template<typename T> void Swap( T& left, T& right) { Ttemp = left; left = right; right = temp; } 注意:**typename关键字是用来定义模板参数关键字,也可以使用class(切记:不能使用struct来代替class)** #### 2.3 函数模板的原理 #### 如何解决上面的问题?大家都知道,瓦特改良了蒸汽机,人类开始了工业革命,解放了生产力。机器生产淘汰了很多的手工产品。本质是什么,重复的工作交给了机器做。有人给出了结论:懒人创造了世界 **函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板是将本来我们做的事情交给了编译器** ![在这里插入图片描述][3e5ce47e12bd4e4ca7df54509e39a11c.png] 在编译器编译阶段:对于模板函数的使用,**编译器需要根据传入的实参类型来推演生成对应类型的函数**以供调用。比如:double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后生产一份专门处理double类型的代码,对于字符类型也是如此。 #### 2.4 函数模板的实例化 #### **用不同类型的参数使用函数模板时**,称为函数模板的实例化。模板参数实例化分为:**隐式实例化和显式实例化** 1. 隐式实例化:让编译器根据实参推演模板参数的实际类型 template<class T> T Add(const T& left, const T& right) { return left + right; } int main() { int a1 = 10, a2 = 20; double d1 = 10.0, d2 = 20.0; Add(a1, a2); Add(d1, d2); /* 该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型 通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错 注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅 Add(a1, d1); */ // 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化 Add(a, (int)d); return 0; } 1. 显式实例化:在函数名后的<>中指定模板参数的实际类型 int main(void) { int a = 10; double b = 20.0; // 显式实例化 Add<int>(a, b); return 0; } 如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错 #### 2.5 模板参数的匹配原则 #### 1. 一个非模板函数可以和一个同名函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数 // 专门处理int的加法函数 int Add(int left, int right) { return left + right; } // 通用加法函数 template<class T> T Add(T left, T right) { return left + right; } void Test() { Add(1, 2); // 与非模板函数匹配,编译器不需要特化 Add<int>(1, 2); // 调用编译器特化的Add版本 } 1. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生一个实例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板 // 专门处理int的加法函数 int Add(int left, int right) { return left + right; } // 通用加法函数 template<class T1, class T2> T1 Add(T1 left, T2 right) { return left + right; } void Test() { Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化 Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数 } 1. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换 ### 3. 类模板 ### #### 3.1 类模板的定义格式 #### template<class T1, class T2, ..., class Tn> class 类模板名 { // 类内成员定义 }; #### 3.2 类模板的实例化 #### 类模板实例化与函数模板实例化不同,**类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类** // Vector类名,Vector<int>才是类型 Vector<int> s1; Vector<double> s2; [3e5ce47e12bd4e4ca7df54509e39a11c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/26/053596d10a9041f999f624b3e4c76c9e.png
相关 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 妖狐艹你老母/ 2024年04月22日 12:10/ 0 赞/ 81 阅读
相关 c++模板初阶 前言 在我们学习c语言中,我们发现很多逻辑一样但函数的数据类型不一样,我们都需重新写,这样就有点代码冗余了。当来到了c++就可以很好的解决这一问题,运用模板。这个模板其实 逃离我推掉我的手/ 2024年04月01日 17:47/ 0 赞/ 106 阅读
相关 【C++初阶】函数模板与类模板 文章目录 引言.泛型编程 一.函数模板 1.基本使用 2.拔高训练 2-1自动推演实例化和显式实例化 忘是亡心i/ 2024年04月01日 15:11/ 0 赞/ 93 阅读
相关 【C++初阶】:模板初阶 模板初阶 一.函数模板 1.简单使用 2.模板原理 3.函数模板的实例化 4.模板参数的匹配原则 二.类 短命女/ 2024年03月22日 19:12/ 0 赞/ 104 阅读
相关 【C++初阶】:模板进阶 模板进阶 一.非类型模板参数 二.模板的特化 1.概念 2.函数模板特化 3.类的特化 1.全特化 雨点打透心脏的1/2处/ 2024年03月18日 00:20/ 0 赞/ 125 阅读
相关 【C++精华铺】8.C++模板初阶 目录 1. 泛型编程 2. 函数模板 2.1 函数模板的概念及格式 2.2 函数模板的原理 2.3 模板的实例化 2.4 模板参数的匹配原则 3. 类模板 た 入场券/ 2023年10月14日 21:26/ 0 赞/ 27 阅读
相关 模板初阶 一、泛型编程 1、函数重载的缺点: (1)重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数 (2)代码的可维护性比较低,一个 拼搏现实的明天。/ 2022年03月21日 04:30/ 0 赞/ 230 阅读
相关 【C++】模板初阶 文章目录 一、泛型编程 二、函数模板 1.函数模板概念 2.函数模板格式 3.函数模板的实例化 三、类模板 本是古典 何须时尚/ 2021年09月09日 03:40/ 0 赞/ 376 阅读
还没有评论,来说两句吧...