模板初阶 拼搏现实的明天。 2022-03-21 04:30 230阅读 0赞 一、泛型编程 1、函数重载的缺点: (1)重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数 (2)代码的可维护性比较低,一个出错可能所有的重载均出错 2、泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的一种。 3、模板又包括:函数模板和类模板。 二、函数模板 1、概念:函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型模板。 2、格式: template<typename T1, typename T2, ... ,typename Tn> 返回类型 函数名(参数列表)\{\} template<typename T> void Swap(T& left, T& right) { T temp = left; left = right; right = temp; } *注:typename是用来定义模板参数关键字,也可以使用class(不能用struct代替class)* 3、函数模板的原理 模板本身不是函数,是编译器用使用方式产生特定具体函数的模具。 编译器需要根据传入的实参类型来推演生成对应类型的函数。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pEXzAxMg_size_16_color_FFFFFF_t_70] 4、函数模板的实例化 用不同类型的参数使用函数模板时,称为函数的实例化。 (1)隐式实例化:让编译器根据实参推演模板参数的实际类型 template<class T> T Add(const T& a, const T& b) { return a + b; } int main() { int a1 = 10, a2 = 20; double d1 = 10.1, d2 = 20.0; Add(a1, a2); Add(d1, d2); /*该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型, 通过实参a1将T推演为int,通过实参d1将T推演为double,但模板参数列表只有一个T, 编译器无法确定此处到底是将T确定为int还是double而报错 Add(a1, d1);*/ //此时有两种处理方式:用户自己来强制转化;使用显示实例化 Add(a1, (int)d1); return 0; } (2)显示实例化:在函数名后的<>中指定模板参数的实际类型 int main() { int a = 10; double d = 20.0; Add<int>(a, d); return 0; } 如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。 5、模板参数的匹配原则 (1)一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非函数模板。 int Add(int a, int b) { return a + b; } template<class T> T Add(T a, T b) { return a + b; } void Test() { Add(1, 2); //与非函数模板类型完全匹配,不需要函数模板实例化 Add<int>(1, 2); //模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数 } (2)对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生一个实例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板。 int Add(int a, int b) { return a + b; } template<class T1, class T2> T Add(T1 a, T2 b) { return a + b; } void Test() { Add(1, 2); Add(1, 2.0); } (3)模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。 三、类模板 1、类模板的定义格式 template<class T1, class T2, ..., class Tn> class 类模板名 { //类内成员定义 }; 动态顺序表 template<class T> class Vector { public: Vector(size_t capacity = 10) :_pData(new T[capacity]) , _size(0) , _capacity(capacity) {} ~Vector(); void PushBack(const T& data) { _pData[_size++] = data; } void PopBack() { --_size; } size_t Size() { return _size; } T& operator[](size_t pos) { assert(pos < _size); return _pData[pos]; } private: T* _pData; size_t _size; size_t _capacity; }; template <class T> Vector<T>::~Vector() { if (_pData) { delete[] _pData; } } 2、类模板的实例化 类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可。 类模板名字不是真正的类,而实例化的结果才是真正的类。 int main() { Vector<int> s1; s1.PushBack(1); s1.PushBack(2); s1.PushBack(3); Vector<double> s2; s2.PushBack(1.0); s2.PushBack(2.0); s2.PushBack(3.0); for (size_t i = 0; i < s1.Size(); i++) { cout << s1[i] << " "; } cout << endl; for (size_t i = 0; i < s2.Size(); i++) { cout << s2[i] << " "; } cout << endl; } [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pEXzAxMg_size_16_color_FFFFFF_t_70]: /images/20220321/62d51132d2d5476a801fa459f9bee521.png
相关 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶) 妖狐艹你老母/ 2024年04月22日 12:10/ 0 赞/ 82 阅读
相关 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 阅读
还没有评论,来说两句吧...