【C++】详解C++的模板

目录

概念

​编辑

 语法

函数模板

类模板

 非类型模板参数

模板的特化

函数模板特化

类模板特化

全特化

偏特化

分离编译


概念

模板是C++中非常厉害的设计,模板把通用的逻辑剥离出来,让不同的数据类型可以复用同一种模板的逻辑,甚至可以让不同的逻辑复用同一种模板逻辑(仿函数的设计)

【C++】详解STL的适配器容器之一:优先级队列 priority_queue-CSDN博客

模板可以帮助我们实现代码的重用和泛化,提高代码的灵活性和可维护性。

STL的容器就是对模板很好的运用,可参考

【C++】详解STL容器之一的 vector-CSDN博客

【C++】详解STL的容器之一:list-CSDN博客

 语法

template <typename T> //可以写成template <class T> 
class MyClass {// ...
};template <typename T> //可以写成template <class T> 
T add(T a, T b) {return a + b;
}

在上面的示例中,MyClass 是一个类模板,add 是一个函数模板。通过使用 typename class 关键字声明模板参数T 就是未知类型

函数模板

通过使用函数模板,我们可以定义一种通用的函数,可以根据实际需要传不同的数据复用函数模板

函数模板的语法格式如下

template <typename T>
返回类型 函数名(参数列表) {// 函数体
}

其中,template关键字表示这是一个函数模板,<typename T>表示定义了一个类型参数T,可以根据需要使用不同的类型来替换T返回类型表示函数的返回类型,函数名表示函数的名称,参数列表表示函数的参数列表。

在函数模板中,可以使用类型参数T作为函数的参数类型、返回类型或局部变量的类型。例如:

template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}

上述代码定义了一个函数模板max,它接受两个参数a和b,这两个参数的类型都是T,并且返回类型也是T

使用函数模板时,需要在函数名后面加上尖括号<>,并在其中指定具体的类型。例如:

int result1 = max<int>(3, 5); // 使用int类型实例化函数模板
double result2 = max<double>(3.14, 2.71); // 使用double类型实例化函数模板

max<int>表示使用`int`类型实例化max函数模板,max<double>表示使用double类型实例化max函数模板。传不同的参数示例化的函数是不同的

函数模板还可以有多个类型参数,可以使用逗号分隔它们。例如:

template <typename T1, typename T2>
void printPair(T1 a, T2 b) {cout << "(" << a << ", " << b << ")" << endl;
}

使用函数模板时,需要指定每个类型参数的具体类型。例如:

printPair<int, double>(3, 3.14); // 使用int和double类型实例化函数模板

在上述代码中,printPair<int, double>表示使用int类型和double类型实例化printPair函数模板。

总结起来,函数模板是一种通用的函数定义,可以用于多种不同类型的参数。通过使用函数模板,可以编写一次代码,然后在不同的地方使用不同的数据类型进行调用。

类模板

通过使用类模板,我们可以定义一种通用的类模板,可以根据实际需要在不同场景下传入不同的类型实例化出不同的类。

类模板的语法格式如下:

template <typename T> //可以写成template <class T>
class 类名 {// 成员变量和成员函数的定义
};

在类模板中,可以使用类型参数T作为成员变量的类型、成员函数的参数类型或返回类型。例如:

template <typename T>
class Stack {
private:T* data;int size;
public:Stack(int capacity) {data = new T[capacity];size = 0;}void push(T value) {data[size++] = value;}T pop() {return data[--size];}
};

上述代码定义了一个类模板Stack,它有一个私有成员变量data和size,分别表示存储数据的数组和当前栈的大小。类模板还有两个公有成员函数push和pop,分别用于向栈中压入元素和弹出栈顶元素。

使用类模板时,需要在类名后面加上尖括号<>,并在其中指定具体的类型。例如:

Stack<int> intStack(10); // 使用int类型实例化类模板
Stack<double> doubleStack(5); // 使用double类型实例化类模板

不然会报如下错误

Stack<int>表示使用int类型实例化Stack类模板,Stack<double>表示使用double类型实例化Stack类模板。根据实际的类型参数,编译器会生成相应的类定义。

类模板还可以有多个类型参数,可以使用逗号分隔它们。例如:

template <typename T1, typename T2>
class Pair {
private:T1 first;T2 second;
public:Pair(T1 a, T2 b) {first = a;second = b;}void print() {cout << "(" << first << ", " << second << ")" << endl;}
};

使用类模板时,需要指定每个类型参数的具体类型。例如:

Pair<int, double> p1(3, 3.14); // 使用int和double类型实例化类模板
Pair<string, int> p2("Hello", 5); // 使用string和int类型实例化类模板

 非类型模板参数

模板参数分为:类型形参非类型形参
类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称
非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用
// 定义一个模板类型的静态数组template<class T, size_t N = 10>class array{public:T& operator[](size_t index){return _array[index];}const T& operator[](size_t index)const{return _array[index];}size_t size()const{return _size;}bool empty()const{return 0 == _size;}private:T _array[N];size_t _size;};
浮点数、类对象以及字符串是不允许作为非类型模板参数的
非类型的模板参数必须在编译期就能确认结果

模板的特化

概念:

在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。模板特 化中分为函数模板特化与类模板特化

函数模板特化

必须要先有一个基础的函数模板
关键字 template 后面接一对空的尖括号 <>
函数名后跟一对尖括号,尖括号中指定需要特化的类型
函数形参表 必须要和模板函数的基础参数类型完全相同
// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{return left < right;
}
// 对Less函数模板进行特化
template<>
bool Less<Date*>(Date* left, Date* right) //Date是日期类
{return *left < *right;
}

下面是测试

关于日期类小编也写了一篇文章:【C++】如何用C++写一个日期计算器-CSDN博客

类模板特化

全特化

全特化即是将模板参数列表中所有的参数都确定化
template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
template<>
class Data<int, char>
{
public:Data() {cout<<"Data<int, char>" <<endl;}
private:int _d1;char _d2;
};

下面是测试

偏特化

任何针对模版参数进一步进行条件限制设计的特化版本
偏特化有以下两种表现方式:
部分特化    
特化一部分参数
下面是测试代码
template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
template <class T1>
class Data<T1, int>
{
public:Data() {cout<<"Data<T1, int>" <<endl;}
private:T1 _d1;int _d2;
};
限制参数
偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本
下面是测试代码
template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
//两个参数偏特化为指针类型
template <typename T1, typename T2>
class Data <T1*, T2*>
{ 
public:Data() {cout<<"Data<T1*, T2*>" <<endl;}private:
T1 _d1;T2 _d2;
};
//两个参数偏特化为引用类型
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:Data(const T1& d1, const T2& d2): _d1(d1), _d2(d2){cout<<"Data<T1&, T2&>" <<endl;}private:const T1 & _d1;const T2 & _d2; };

分离编译

下面了解即可

C/C++程序要运行要经历以下步骤

预处理---> 编译---> 汇编---> 链接

预处理:将头文件展开

编译:头文件不参与编译,编译主要是检查语法错误,多个源文件单独分开编译

汇编:将文本文件翻译成二进制文件

链接:将多个编译好的源文件合成一个

如果将模板声明和定义分离会报链接错误

可参考下面这位大佬的文章

为什么C++编译器不能支持对模板的分离式编译-CSDN博客

 将声明和定义放到一个文件 "xxx.hpp" 里面或者xxx.h其实也是可以的。推荐使用这种
 模板定义的位置显式实例化。这种方法不实用,不推荐使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/12296.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter 中的 DataTable 小部件:全面指南

Flutter 中的 DataTable 小部件&#xff1a;全面指南 在Flutter的Material组件库中&#xff0c;DataTable是一个用于展示数据的表格组件&#xff0c;它允许开发者以一种结构化和可滚动的方式展示数据集。DataTable非常适合展示详细信息&#xff0c;如表格数据、统计数据或配置…

PHP黑魔法之md5绕过

php本身是一种弱语言,这个特性决定了它的两个特点: 输入的参数都是当作字符串处理变量类型不需要声明,大部分时候都是通过函数进行类型转化php中的判断有两种: 松散比较:只需要值相同即可,类型不必相同,不通类型比较会先转化为同类型,比如全数字字符串和数字比较,会比…

凸优化理论学习三|凸优化问题(一)

系列文章目录 凸优化理论学习一|最优化及凸集的基本概念 凸优化理论学习二|凸函数及其相关概念 文章目录 系列文章目录一、优化问题&#xff08;一&#xff09;标准形式的优化问题&#xff08;二&#xff09;可行点和最优点&#xff08;三&#xff09;局部最优点&#xff08;四…

《Python编程从入门到实践》day28

# 昨日知识点回顾 安装Matplotlib 绘制简单的折线图 # 今日知识点学习 15.2.1 修改标签文字和线条粗细 # module backend_interagg has no attribute FigureCanvas. Did you mean: FigureCanvasAgg? # 解决办法&#xff1a;matplotlib切换图形界面显示终端TkAgg。 #…

使用Three.js绘制快速而逼真的水

本文将利用GPUComputationRenderer来实现水波纹的绘制&#xff0c;相似的案例可以看threejs官方的GPGPU Water示例。更多精彩内容尽在数字孪生平台。 什么是 GPGPU GPGPU代表通用图形处理单元&#xff08;General-Purpose Graphic Processing Unit&#xff09;&#xff0c;意思…

1146 -Table ‘performance schema.session variables‘ doesn‘t exist的错误解决

一、问题出现 今天在本地连数据库的时候&#xff0c;发现这个问题&#xff0c;哎呦我擦&#xff0c;差点吓死了 二、解决办法 1&#xff09;找文件 用everything搜一下MySQL Server 5.7 然后去Windows服务找一下MySQL配置文件的具体路径 如果知道那最好&#xff0c;不知道那…

宝塔8.1.0去除绑定用户

非要绑定手机号&#xff0c;确实很烦 1&#xff0c;/www/server/panel/BTPanel __init__.py if not public.is_bind():return redirect(/bind, 302) 将is_bind的路由全部注释 2&#xff0c;/www/server/panel/class下 panelPlugin.py 注释异常&#xff0c; 新增 softLis…

SSL协议

SSL 安全传输协议&#xff08;安全套接层&#xff09; 也叫TLS ---- 传输层安全协议 SSL的工作原理&#xff1a;SSL协议因为是基于TCP协议工作的&#xff0c;通信双方需要先建立TCP会话。因为SSL协议需要进行安全保证&#xff0c;需要协商安全参数&#xff0c;所以也需要建立…

【MySQL】7.MySQL性能优化的六大核心策略

数据库的性能对整个应用的响应速度和用户体验起着至关重要的作用。MySQL&#xff0c;作为广泛使用的开源关系型数据库&#xff0c;提供了丰富的性能优化手段。从资源优化、查询优化到结构、配置、代码乃至架构优化&#xff0c;每一个层面的调整都可能带来性能的飞跃。本文将深入…

springboot房屋租赁系统

摘要 房屋租赁系统&#xff1b;为用户提供了一个房屋租赁系统平台&#xff0c;方便管理员查看及维护&#xff0c;并且可以通过需求进行设备信息内容的编辑及维护等&#xff1b;对于用户而言&#xff0c;可以随时进行查看房屋信息和合同信息&#xff0c;并且可以进行报修、评价…

清理缓存简单功能实现

在程序开发中&#xff0c;经常会用到缓存&#xff0c;最常用的后端缓存技术有Redis、MongoDB、Memcache等。 而有时候我们希望能够手动清理缓存&#xff0c;点一下按钮就把当前Redis的缓存和前端缓存都清空。 功能非常简单&#xff0c;创建一个控制器类CacheController&#xf…

SpringBoot PowerMockito 私有/静态/方法/属性

SpringBoot PowerMockito 私有/静态/方法/属性 1 PrepareForTest2 待测试类3 测试类 1 PrepareForTest PrepareForTest 是 PowerMockito 提供的一个注解&#xff0c;用于告诉 PowerMockito 哪些类需要被修改以允许使用 PowerMockito 的功能。 PowerMockito 主要用于修改 Java…

【计算机毕业设计】基于SSM+Vue的线上旅行信息管理系统【源码+lw+部署文档+讲解】

目录 1 绪论 1.1 研究背景 1.2 设计原则 1.3 论文组织结构 2 系统关键技术 2.1JSP技术 2.2 JAVA技术 2.3 B/S结构 2.4 MYSQL数据库 3 系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 操作可行性 3.1.3 经济可行性 3.1.4 法律可行性 3.2系统功能分析 3.2.1管理员功能分析 3.2.…

JavaScript精粹(一)

JavaScript&#xff08;简称为JS&#xff09;是一种广泛应用于网页开发的脚本语言&#xff0c;具有以下几个主要作用&#xff1a; 网页交互&#xff1a;JavaScript 可以用于创建动态的网页效果&#xff0c;例如响应用户的操作&#xff0c;实现页面内容的动态更新&#xff0c;以…

Java SE vs Java EE:深入剖析及面试指南

Java 平台提供了多个版本来满足不同应用场景的需求&#xff0c;其中最常用的是 Java SE&#xff08;Standard Edition&#xff09;和 Java EE&#xff08;Enterprise Edition&#xff09;。理解这两个版本的区别对于任何 Java 开发者都是至关重要的&#xff0c;尤其是在面试过程…

C++字符串细节,面试题06

文章目录 22. 字符串22.1. 字符数组 vs 字符指针 vs 常量字符指针 vs string22.2. strcpy vs sprintf vs memcpy22.3. strlen vs length vs size vs sizeof22.4. 字符串之间的转换22.5 其他数据类型与字符串之间的转换22.6 字符串分割 22. 字符串 22.1. 字符数组 vs 字符指针 …

Spring整合其他技术

文章目录 Spring整合mybatis思路分析Mybatis程序核心对象分析整合Mybatis 代码实现 Spring整合Junit修改成警告 Spring整合mybatis 思路分析 Mybatis程序核心对象分析 上面图片是mybatis的代码&#xff0c;上述有三个对象&#xff0c;分别是sqlSessionFactory&#xff0c;sqlS…

Linux:配置客户端自定义autofs服务

Linux&#xff1a;配置客户端自定义autofs服务 修改autofs的主策略文件 [rootserver200 data]# vim /etc/auto.master# 修改内容如下 /misc /etc/auto.misc # 挂载目录的上级目录 /mnt /etc/auto.timinglee --timeout3修改autofs的自定义策略文件 [rootserver200 data]…

数据库SQL编写规范-SQL书写规范整理(SQL语句书写规范全解-Word原件)

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目 2 SQL书写规范 3 SQL编写原则 软件全套精华资料包清单部分文件列表&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说…

鸿蒙布局Column/Row/Stack

鸿蒙布局Column/Row/Stack 简介我们以Column为例进行讲解1. Column({space: 10}) 这里的space: 10&#xff0c;表示Column里面每个元素之间的间距为102. width(100%)&#xff0c;height(100%) 表示宽高占比3. backgroundColor(0xffeeeeee) 设置背景颜色4. padding({top: 50}) 设…