您现在的位置是:首页 > 短信大全

【C++】模板

作者:胡椒时间:2024-04-09 18:25:23分类:短信大全

简介  文章浏览阅读1.3k次,点赞61次,收藏47次。C++模板介绍

点击全文阅读

1. 模板参数分类

模板参数分成两种:

一种是 非类型形参 和 类型形参

类型形参:

举例

template<class T>struct less{bool operator()(const T& x, const T& y){return x > y;}};

 

非类型形参:

举例

template<size_t x>class arry{private:int _arr[x];};

这里数组的大小可以被固定住,取决于 x

注意:

非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量(不可以被修改)来使用 ,常量是整型类型(如:size_t ,int ,long , char 等等)非类型的模板参数必须在编译期就能确认结果

2. 模板的特化

对于某些特殊的类型,使用模板可能会得到一些的错误的结果

如:日期类的比较

举例

#include<iostream>using namespace std;template<class T>bool less(const T x, const T y){ return x > y;};int main(){   Data t1(2024,3,6);   Data t2(2021,6,7);   cout << less(t1,t2) << endl;  //这种比较得到的是正确的   Data* p1 = new Data(2024,3,6);   Data* p2 = new Data(2021,6,7);   cout << less(p1,p2) << endl; //这种比较结果不一定正确}

分析:

p1 和 p2 都是动态开辟出来的空间,实际上 less 比较的是它们的地址的高低

a. 函数模板特化

函数模板的特化步骤:

1. 必须要先有一个基础的函数模板

2. 关键字template后面接一对空的尖括号<>

3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型

4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误

代码举例

template<class T>bool less(const T x,const T y){ return x > y;};template<>bool less<Data *>(const Data *x,const Data *y){return *x > *y;};

注意:

一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出

代码举例

bool less(const Data *x,const Data *y){return *x > *y;};

这样的代码的可读性高,容易书写,因为对于一些参数类型复杂的函数模板,特化时直接给出,因此函数模板不建议特化

b. 类模板特化

(1)全特化

全特化即是将模板参数列表中所有的参数都确定化

代码举例

template<class T1, class T2>class AA{public:AA(){cout << "T1 T2" << endl;}private:T1 _a;T2 _b;};template<>class AA<int,char>{public:AA(){cout << "int char" << endl;}private:int _a;char _b;};void test2(){AA<int, int> t1;AA<int, char> t2;}

运行结果:

 

(2)偏特化

偏特化有两种:

一种是 部分特化: 将模板参数类表中的一部分参数特化

代码举例

template<class T1, class T2>class AA{public:AA(){cout << "T1 T2" << endl;}private:T1 _a;T2 _b;};template<class T1>class AA<T1,char>{public:AA(){cout << "T1 char" << endl;}private:T1 _a;char _b;};void test2(){AA<int, int> t1;AA<int, char> t2;}

运行结果:

 另一种是 参数更进一步的限制

代码举例

template<class T1, class T2>class AA{public:AA(){cout << "T1 T2" << endl;}private:T1 _a;T2 _b;};template<class T1,class T2>class AA<T1*,T2*> // 限制 T1,T2 是指针类型{public:AA(){cout << "T1* T2*" << endl;}private:T1* _a;T2* _b;};void test2(){AA<int, int> t1;AA<int*, char*> t2;}

运行结果:

注意:

特化必须在原模板的基础之上,它不是全新的模板

3. 模板分离编译

模板不支持分离编译(声明和定义不在一个文件)

a. 失败原因

分析原因:

预处理阶段:

头文件展开,去掉注释,替换宏,条件编译

编译:

检查语法,生成汇编代码(一串指令)

汇编:

将汇编代码转换成二进制机器码

链接:

合成生成可执行文件

由此我们直到,在编译的时候,无法实例化模板,因为模板参数的类型是无法确定的,也无法生成汇编代码

b. 解决方案

声明和定义都放在同一个.h文件中 

代码举例

test.h

namespace lhy{template<class T>class Add{public:Add():x(T()), y(T()){}int add();private:T x;T y;};template<class T>int Add<T> ::add(){return x + y;}}

test.cpp 

using namespace std;#include "test.h"int main(){lhy::Add<int> t;cout << t.add() << endl;}

运行结果:

4. 模板总结

【优点】

1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生

2. 增强了代码的灵活性

【缺陷】

1. 模板会导致代码膨胀问题,也会导致编译时间变长

2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

上一篇:美文摘抄

下一篇:返回列表

我来说两句