【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 妖狐艹你老母 2024-04-22 12:10 82阅读 0赞 ![35ba644c47a446c987619bb756c68cb6.gif][] ## 一.泛型编程 ## ### 引入 ### > 我们之前都写过交换函数Swap,例如这样的: > > //交换两个整型 > void Swap(int*x1, int *x2) > { > int tmp = *x1; > *x1 = *x2; > *x2 = tmp; > > } > > 如果要交换其它的类型该怎么办呢? > > 那只能当个CV工程师了,然后再修修改改,但是如果有很多类型呢?后期又需要改动该怎么办呢?一个一个函数的改吗?多个功能相同的函数,又会使程序**可读性降低,代码冗余**。 > > 我们能用一个具有交换函数逻辑的模具,来实现不同需求吗? > > 答案是可以,用模板就可以了。 ### 模板 ### > **泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础** > 语法:**template<class/typename 参数,class/typename 参数 .......>** > > 注意:**class 或是 typename** 是用来定义模板参数的**关键字**,不可以使用 **struct**,并且可 以定义**多个模板参数**。 > > 模板分为两种: > > **1.函数模板** > > **2.类模板** > > 注意:**类模板和模板类不是同一个概念**(详见下文) 示例:Swap模板 template<typename T> //这个模板的作用域是下面的一个大括号,当然也可以有多个模板参数 void Swap(T& x1, T& x2) //注意这里要用引用 { T tmp = x1; x1 = x2; x2 = tmp; } ![7be2b5fb89b44966aae40534b2834cba.png][] -------------------- ## 二.函数模板 ## ### 概念 ### > 函数模板代表了**一个函数家族**,该函数模板**与类型无关**,在使用时被参数化,根据实参类型产生函数的特定类型版本。 > > **编译器由模板生成函数的过程称为实例化**。 > > 上文中的Swap模板就是一个函数模板。 ### 隐式实例化 ### > **隐式实例化是指编译器根据实参自己推演参数的类型,并生成对应的函数;** > > 以Swap函数模板为例: > > template<typename T> > void Swap(T &x1, T &x2) > { > T tmp = x1; > x1 = x2; > x2 = tmp; > } > > int main() > { > int a1 = 1, a2 = 2; > double b1= 5.2, b2 = 6.4; > char c1 = 'a', c2 = 'e'; > Swap(a1, a2); cout << a1 << " " << a2 << endl; > Swap(b1, b2); cout << b1 << " " << b2 << endl; > Swap(c1, c2); cout << c1 << " " << c2 << endl; > > return 0; > > } > > ![76a6cdbdf65f46fda5aca9c4feb353f1.png][] > > **即使它们用的是同一个模板,但他们调用的并不是同一个函数**,从汇编中就可以看出来: > > ![0257515058b54a10adc2ac2a0da42bb4.png][] > > ![c56e14a5038d4e99aaada76755917f52.png][] ### 显式实例化 ### > **语法:函数名<类型>(实参1,实参2.....)** > > 例: > > template<typename T> > void Swap(T &x1, T &x2) > { > T tmp = x1; > x1 = x2; > x2 = tmp; > } > > int main() > { > int a1 = 1, a2 = 2; > double b1= 5.2, b2 = 6.4; > char c1 = 'a', c2 = 'e'; > Swap<int>(a1, a2); //显式实例化 > return 0; > > } > 其实有的时候我们不得不显示实例化模板: > > ![16ad965547004780ba6dbe77e443846d.png][] ### 模板参数的匹配原则 ### > 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版本 > } > 2. 对于非模板函数和同名函数模板,**如果其他条件都相同,在调动时会优先调用非模板函 数而不会从该模板产生出一个实例**。如果模板可以产生一个具有更好匹配的函数, 那么 将选择模板 > > 如下动图所示: > > ![a9ef5328e3814f8d92f644d059260030.gif][] > 3. **模板函数不允许自动类型转换,但普通函数可以进行自动类型转换**。 -------------------- ## 三.类模板 ## ### 定义格式 ### template<class T1, class T2, ..., class Tn> //typename也可以 class 类模板名 { // 类内成员定义 }; ### 类模板的实例化 ### > 类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,也就是**要显式实例化**; > > 注意:**类模板名字不是真正的类,而实例化的结果才是真正的类** > > 例: > > // Stack是类名,Stack<int>才是类型 > Stack<int> s1; > Stack<double> s2; ### 类模板和模板类的区别 ### #### 类模板 #### > **类模板是指定义一个通用的类模板,其中包含一个或多个类型参数**,这些类型参数可以在实例化时被替换为具体的类型。 > > 例: > > template <typename T> > class MyContainer > { > public: > void add(T element); > T get(int index); > private: > T elements[100]; > int size; > }; > > 在这个例子中: > > 1,**\`MyContainer\` 是一个类模板**; > > 2,**\`T\` 是一个类型参数**,可以在实例化时被替换为具体的类型,例如 \`int\` 或 \`double\`。 #### 模板类 #### > **模板类是指使用类模板生成的具体类**。 > > 例: > > //..... > MyContainer<int> intContainer; > MyContainer<double> doubleContainer; > //..... > > 在这个例子中: > > 1,**\`MyContainer<int>\` 和 \`MyContainer<double>\` 都是模板类**; > > 2,**它们是使用类模板 \`MyContainer\` 生成的具体类**,分别用于存储 \`int\` 和 \`double\` 类型的 元素。 -------------------- > **??本篇文章到此就结束了, 若有错误或是建议的话,欢迎小伙伴们指出;?️?** > > **??希望小伙伴们能支持支持博主啊,你们的支持对我很重要哦;??** > > **??谢谢你的阅读。??** ![9f16e03bc8c649d796d0306f0a6b9e06.gif][] [35ba644c47a446c987619bb756c68cb6.gif]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/d953021c14ef44d3ac86860f48977bdc.gif [7be2b5fb89b44966aae40534b2834cba.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/b1282b5f0e4a464c8724c8c5951f4a49.png [76a6cdbdf65f46fda5aca9c4feb353f1.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/552ff05b31864faaa0a3bf93330447e1.png [0257515058b54a10adc2ac2a0da42bb4.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/0dd4f41e672b4da181c72d2e461a9bda.png [c56e14a5038d4e99aaada76755917f52.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/110ce2fea29a433a937a877be72e4dc8.png [16ad965547004780ba6dbe77e443846d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/05cb861a70b84b5aaad6fdba775c8790.png [a9ef5328e3814f8d92f644d059260030.gif]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/7f7062bd20f346cb87c7f31786e9398a.gif [9f16e03bc8c649d796d0306f0a6b9e06.gif]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/22/e7b77277dff64ec7b66e6993da0e134a.gif
相关 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 妖狐艹你老母/ 2024年04月22日 12:10/ 0 赞/ 83 阅读
相关 c++模板初阶 前言 在我们学习c语言中,我们发现很多逻辑一样但函数的数据类型不一样,我们都需重新写,这样就有点代码冗余了。当来到了c++就可以很好的解决这一问题,运用模板。这个模板其实 逃离我推掉我的手/ 2024年04月01日 17:47/ 0 赞/ 106 阅读
相关 【C++初阶】函数模板与类模板 文章目录 引言.泛型编程 一.函数模板 1.基本使用 2.拔高训练 2-1自动推演实例化和显式实例化 忘是亡心i/ 2024年04月01日 15:11/ 0 赞/ 94 阅读
相关 【C++初阶】:模板初阶 模板初阶 一.函数模板 1.简单使用 2.模板原理 3.函数模板的实例化 4.模板参数的匹配原则 二.类 短命女/ 2024年03月22日 19:12/ 0 赞/ 106 阅读
相关 【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 赞/ 28 阅读
相关 模板初阶 一、泛型编程 1、函数重载的缺点: (1)重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数 (2)代码的可维护性比较低,一个 拼搏现实的明天。/ 2022年03月21日 04:30/ 0 赞/ 231 阅读
相关 【C++】模板初阶 文章目录 一、泛型编程 二、函数模板 1.函数模板概念 2.函数模板格式 3.函数模板的实例化 三、类模板 本是古典 何须时尚/ 2021年09月09日 03:40/ 0 赞/ 376 阅读
还没有评论,来说两句吧...