C++_模板初阶

在面向对象中,我们可以使用重载来实现多态。

但是问题在于,重载的函数仅仅是类型不同,代码复用率比较低,只要有新的类型出现时,就要增加对应的函数;另一方面它的代码可维护性比较低,一个出错可能所有的重载均出错。

那么在C++中,我们可以使用模板来尽量避免这些问题。

一、函数模板

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

函数模板格式如下:

template<typename T1, typename T2,......,typename Tn>

返回值类型 函数名(参数列表){}

其中,typename是用来定义模板参数关键字,也可以使用class。

要注意模板和函数之间是不需要任何符号的,并且它们可以在同一行。

下面的代码就是使用函数模板的一个实例:

template <typename T>
void Swap(T& left,T& right)
{T temp = left;left = right;right = temp;
}

函数模板本身不是一个函数,而是“蓝图”,是编译器用使用方式产生特定具体类型函数的模具。

模板就是将本来应该我们做的重复的事情交给了编译器。

当使用了模板时,在编译器编译阶段,编译器需要根据传入的实参类型来推演生成对应的函数,然后供调用。

假如我们用double类型使用函数模板时,编译器通过对实参类型的推演,确定T为double,然后生成专门处理double类型参数的函数:

可以看到,类型仍然为double,变量的值也被成功交换。

实例化函数模板的方式有两种,一种是隐式实例化,另一种是显式实例化。

隐式实例化,即让编译器根据实参推演推演模板参数的实际类型,例如:

从监视1窗口可以看到,得到了正确的结果。

那么,根据刚才的Add函数模板及变量,能否这样隐式实例化呢?

Add(num0,num2);

根据编译器警告信息,可以明确是不可行的:

要处理这种状况,方法有两种,一种是用户自己强制类型转换:

Add((double)num0, num2);
Add(num0, (int)num2);

还有一种方法就是,显式实例化。

只需要在函数名后的<>中指定模板参数的实际类型即可显式实例化:

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

模板参数的匹配规则如下:

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数;

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板;

3.模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。

例如,func同时是函数,也是模板。现在在main函数中用不同的类型对其实例化,根据打印输出结果可知,当参数为int时,调用的是函数,当参数不为int时,调用的是根据模板生成的函数:

 二、类模板

类模板是编译器根据被实例化的类型生成具体类的模具。

在STL中,如vector,随处可见类模板的身影:

类模板的定义格式如下:

template <class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};

与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>
中即可。

类模板名字不是真正的类,实例化的结果才是真正的类。

一个类模板实例化的具体例子:

  

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

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

相关文章

java实现文件的下载

系统日志的获取不可能每次都登录服务器&#xff0c;所以在页面上能够下载系统运行的日志是必须的 如何来实现日志的下载&#xff0c;这样的一个功能 前端我们用到的是window.open(...)这样可以发送一个get请求到后台 后台接收到get请求之后&#xff0c;如何实现对文件的下载 R…

ubuntu中redis+mysql安装使用

pip -V 回车&#xff08;大写V&#xff09;&#xff1a;python包库安装路径 python -m site: python查找路径 1、redis ubuntu安装redis System has not been booted with systemd as init system (PID 1). Cant operate&#xff1b;该问题是systemctl start redis报错&#…

ZLMediaKit(webrtc)在linux上(CentOS7)部署与启动

一.ZLMediaKit(webrtc)在CentOS7部署与启动 # 1. 卸载旧版本 yum remove git # 2. 安装 yum 源的 Git 版本 yum install -y git # 3. 查看版本 git version # 输出 git version 1.8.3.1配置全局环境变量 # 1. 编辑配置文件 vim /etc/profile # 2. 在 /etc/profile 文件中末尾…

用 Rufus 制作 Ubuntu 系统启动盘时,选择分区类型为MBR还是GPT?

当使用 Rufus 制作 Ubuntu 系统启动盘时&#xff0c;您可以根据您的需求选择分区类型&#xff0c;MBR&#xff08;Master Boot Record&#xff09;还是 GPT&#xff08;GUID Partition Table&#xff09;。 MBR 是传统的分区表格式&#xff0c;适用于大多数旧版本的操作系统和旧…

2023/08/13_____JMM JAVA Memory Model JAVA内存模型

JMM JAVA Memory Model java内存模型 作用&#xff1a;缓存一致性协议&#xff0c;用于定义数据读写的规则&#xff08;遵守&#xff0c;找到这个规则&#xff09; JMM定义了线程2工作内存和主内存之间的抽象关系&#xff1a;线程之间的共享变量存储在主内存&#xff08;main …

TLS协议

目录 什么是TLS协议&#xff1f; TLS的基本流程&#xff1f; 两种密钥交换算法&#xff1f; 基于ECDHE密钥交换算法的TLS握手过程&#xff1f; 基于RSA密钥交换算法的TLS握手过程&#xff1f; 基于RSA的握手和基于ECDHE的握手有什么区别&#xff1f; 什么是前向保密&…

tp6 v3微信退款

/*** Notes:退款* param $out_trade_no 支付时候订单号&#xff08;order表 original_bn&#xff09;两个参数选一个这个要选对* param $out_refund_no 退款订单号* param $total 订单金额* param $refund 退款金额* Time: 2023-08-10*/public function refundMoney($out_trade…

oracle的异常处理

oracle提供了预定义例外、非预定义例外和自定义例外三种类型。其中&#xff1a; l预定义例外用于处理常见的oracle错误&#xff1b; l非预定义例外用于处理预定义所不能处理的oracle错误&#xff1b; l自定义例外处理与oracle错误无关的其他情况。 Oracle代码编写过程中&am…

nginx反向代理与负载均衡

负载均衡依靠反向代理实现。nginx的代理分为七层代理与四层代理&#xff1a; 七层代理&#xff1a;七层代理的就是http请求和响应。七层代理是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块。而且配置方法名称&#xff1a;upstream模块&#xff0c;不能写…

提升效率!Go语言开发者不可错过的必备工具集合!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to Golang Language.✨✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1…

UDP数据报网络编程(实现简单的回显服务器,客户端)

回显服务器表示客户端发的是啥&#xff0c;服务器就返回啥&#xff0c;主要是为了熟悉UDP数据报网络编程的基本步骤 对于程序的所有分析都写到了代码上 UDP回显服务器代码 package UdpEcho;import java.io.IOException; import java.net.DatagramPacket; import java.net.Dat…

ClickHouse查看执行计划(EXPLAIN语法)

1.EXPLAIN 语法示例 EXPLAIN [AST | SYNTAX | QUERY TREE | PLAN | PIPELINE | ESTIMATE | TABLE OVERRIDE] [setting value, ...] [ SELECT ... | tableFunction(...) [COLUMNS (...)] [ORDER BY ...] [PARTITION BY ...] [PRIMARY KEY] [SAMPLE BY ...] [T…

途乐证券-最准确的KDJ改良指标?

KDJ目标是技术剖析的一种重要目标之一&#xff0c;它是利用随机目标&#xff08;%R&#xff09;发展而来的&#xff0c;是一种反映商场超买和超卖状况的买卖目标。KDJ目标由快线&#xff08;K线&#xff09;、慢线&#xff08;D线&#xff09;和随机值&#xff08;J线&#xff…

RestTemplate HTTPS请求忽略SSL证书

问题描述 使用RestTemplate发送HTTPS请求的时候&#xff0c;出现了这样的一个问题&#xff1a; sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification …

MySQL多表查询

1.创建student和score表 创建score表 2.为student表和score表增加记录 向student表插入记录的INSERT语句如下&#xff1a; 向score表插入记录的INSERT语句如下&#xff1a; 1.查询student表的所有记录 2.查询student表的第2条到4条记录 3.从student表查询所有学生的学号&#…

2023最新影视泛目录系统,苹果cms最新下载地址

影视泛目录系统是指一种集成了电影、电视剧、综艺节目、动漫等多种影视资源资源的系统&#xff0c;其目的是为用户提供一个方便快捷的影视资源检索、浏览、分享、评论的平台。该系统通过对影视资源进行分类、标签化、评分等方式&#xff0c;为用户提供更加精准的检索和推荐服务…

C#多线程学习 生产者和消费者

前面说过&#xff0c;每个线程都有自己的资源&#xff0c;但是代码区是共享的&#xff0c;即每个线程都可以执行相同的函数。这可能带来的问题就是几个线程同时执行一个函数&#xff0c;导致数据的混乱&#xff0c;产生不可预料的结果&#xff0c;因此我们必须避免这种情况的发…

mousedown拖拽功能(vue3+ts)

因为项目有rem适配&#xff0c;使用第三方插件无法处理适配问题&#xff0c;所有只能自己写拖拽功能了 拖拽一般都会想到按下&#xff0c;移动&#xff0c;放开&#xff0c;但是本人亲测&#xff0c;就在div绑定一个按下事件就行了&#xff08;在事件里面写另外两个事件&#x…

爬虫ip池越大越好吗?

作为一名资深的程序员&#xff0c;今天我要给大家分享一些关于爬虫ip池的知识。关于ip代理池的问题&#xff0c;答案是肯定的&#xff0c;池子越大越好。下面跟我一起来盘点一下ip池大的好处吧&#xff01; 1、提高稳定性 爬虫ip池越大&#xff0c;意味着拥有更多可用的爬虫ip…

「C/C++」C/C++搭建程序框架

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C」C/C程序设计「Win」Windows程序设计「DSA」数据结构与算法「File」数据文件格式 目录 1. 分离职…