对模版以及模版中参数的理解

news2024/12/24 9:04:21

所谓模板,实际上是建立一个通用函数或类,其类内部的类型和函数的形参类型不具体指定,用一个虚拟的类型来代表。


就比方说你想要实现 一个Add的加法函数,面对不同的类型,你是否要进行多次函数重载呢,其实这多个函数实现的底层原理都是一样的,只不过是类型不同,所以祖师爷就根据这种情况设计出了模版。


 函数模版

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


格式要求

在定义函数前要写上这一行:template<typename T1, typename T2,......,typename Tn>,这里的typename换成class也是OK的。而函数定义就是正常写,只不过将原来的实例化类型换成虚拟化类型(也就是上一行的T1、T2......)


举例Add函数模版

template<class T>
T Add(const T& a, const T& b)
{
	return a + b;
}

因为这里需要整体替换的就一个类型所以模版形参中给一个T就行。

但是你的类型也必须要进行统一才可以:

int main()
{
	double sum = Add(1.2, 1);
	cout << sum << endl;
}

如果主函数这样写的话,那就会报错:  没有与参数列表匹配的 函数模板 "Add"

这样也有有解决方法:函数模版实例化(实际也是匹配)


函数模版实例化 

函数模版的实例化其实也就是将函数参数进行统一成其中一个模版函数的参数。

隐式实例化

即是不直接告诉编译器参数的类型,让编译器在自己生成的模拟板函数中去找与之匹配的。

template<class T>
T Add(const T& a, const T& b)
{
	return a + b;
}
int main()
{
	double sum = Add(1.2, (double)1);//强制类型转换
	cout << sum << endl;
}

其实这就是一种隐式转换。

其实在你写模版函数时发生了两次编译:

  1. 实例化前,先检查模板代码本身,查看语法是否正确。
  2. 实例化期间,检查模板代码,查看是否所有的调用都有效。

在函数模版生成是就相当于编译器自己生成了多个不同类型的重载函数,在你调用函数模版时,编译器就会在生成的所有重载函数中找一个最匹配的让你调用。

显式实例化 

显示实例化的特点就是在函数名后面加 <type>,type就是你调用函数时的具体类型

int main()
{
	double sum = Add<double>(1.2,1);
	cout << sum << endl;
}

这就相当于直接告诉编译器调用的函数参数类型是double型,所以这就是显式实例化 。


函数模版和模版函数 

这里和你们讲一下这个基本概念,函数模版与模版函数。

首先,它们俩根本就不是一个东西。

函数模版是个模版,它相当于是一个函数家族,而家族成员就是模版函数(一个实例化的函数)而我们一般会写一个函数模版,然后编译器自动生成不同类型的模版函数,再给使用者使用。

 


类模版

template<typename T, int N>
class Test
{
public:
    Test()
        :_arr(new T[N])
    {
        for (int i = 0; i < N; i++)
            _arr[i] = i+0.5;
    }
    ~Test()
    {
        delete[]_arr;
    }

private:
    T* _arr;
};

像这个模版的功能就是单纯的创建一个数组并完成初始化,这里用到了两个模版参数,所以就写成:template<typename T, int N>,int N是数组大小,所以就直接写int类型就行

但是类模版相较于函数模版没有隐式实例化,只能通过显式实例化来创建对象。


类模板中函数放在类外进行定义时,需要加模板参数列表

template<typename T, int N>
class Test
{
public:
    Test();
    ~Test()
    {
        delete[]_arr;
    }

private:
    T* _arr;
};

template<typename T, int N>
Test<T, N>::Test()
:_arr(new T[N])
{
    for (int i = 0; i < N; i++)
        _arr[i] = i + 0.5;
}

不仅仅要加上模版参数列表,还要加上类类型,模版类的类型和一般类的类型是不一样的,模版类的类型=类名+<T1,T2...>,而相较于一般的类而言,类名就是类型

模版参数

现在谈一谈模版的参数,提前声明:模版参数可不是函数参数和类参数,这一定要分开。

模版参数的形参就是模板参数列表中的T,用上面的模版类为例就是有两个模版参数T和N而有了形参,实参也就容易了,就是double和5.



欢迎莅临指导!!!

 

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

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

相关文章

网络安全(黑客)自学的误区

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而…

许战海咨询方法论系列白皮书在京隆重发布

新时代&#xff0c;面对剧烈变化的竞争环境&#xff0c;企业如何实现结构性增长&#xff1f; 7月31日&#xff0c;许战海咨询最新研究成果——《主品牌进化战略》、《第二招牌增长战略》、《链主品牌&#xff1a;制造业的竞争之王》三本核心方法论白皮书&#xff0c;重磅发布。…

移动端网页div下滑消失、上滑出现(附带闪烁效果)

<div :class "IconShow ? mhomeIcon : IconOff"><img src"/assets/news.svg" alt""></div>// 距离顶部的距离const top ref(0) // 图标向上还是向下滑动const IconShow ref(true)// 滑动监听&#xff0c; 注意如果只有doc…

【C++】深入浅出STL之vector类

文章篇幅较长&#xff0c;越3万余字&#xff0c;建议电脑端访问 文章目录 一、前言二、vector的介绍及使用1、vector的介绍2、常用接口细述1&#xff09;vector类对象的默认成员函数① 构造函数② 拷贝构造③ 赋值重载 2&#xff09;vector类对象的访问及遍历操作① operator[]…

zookeeper入门学习

zookeeper入门学习 zookeeper应用场景 分布式协调组件 客户端第一次请求发给服务器2&#xff0c;将flag值修改为false&#xff0c;第二次请求被负载均衡到服务器1&#xff0c;访问到的flag也会是false 一旦有节点发生改变&#xff0c;就会通知所有监听方改变自己的值&#…

c++画出分割图像,水平线和垂直线

1、pca 找到图像某个区域的垂直线&#xff0c;并画出来 // 1、 斑块的框 血管二值化图&#xff0c;pca 找到垂直血管壁的直线, 还是根据斑块找主轴方向吧// Step 1: 提取斑块左右范围内的血管像素点坐标&#xff0c;std::vector<cv::Point> points;for (int y 0; y <…

Stable Diffusion教程(6) - 扩展安装

打开stable diffusion webUI界面 加载插件列表 依次点击扩展->可用->加载自 搜索插件 首先在搜索框输入你要安装的插件&#xff0c;然后点击插件后面的安装按钮 如果你需要的插件这里面没有找到&#xff0c;可通过通网址安装的方式安装。 在git仓库网址输入框输入的你插件…

警惕!中科院预警,Frontiers这本不被收录!2023年7月EI目录已更新!(附全年下载)

2023年7月EI期刊目录更新 爱思唯尔官网近日更新了EI期刊目录&#xff0c;此次更新是2023年7月1日&#xff0c;与上次更新&#xff08;2023年6月&#xff09;相比&#xff0c;有1本期刊名称在Serials&#xff08;连续出版&#xff09;列表中搜索不到&#xff0c;详情如下&#…

InfiniBand、UCIe相关思考

InfiniBand、UCIe相关思考 内容1、InfiniBandInfiniBand是什么&#xff1f;InfiniBand的来历是什么&#xff1f;InfiniBand为什么重要&#xff1f;InfiniBand相较于Ethernet区别&#xff1f;同领域内还有其他哪些技术&#xff1f;InfiniBand中RDMA是种什么技术&#xff1f; 内容…

【Linux】计算机网络的背景和协议分层

文章目录 网络发展协议何为协议网络协议协议分层OSI七层模型TCP/IP五层模型&#xff08;四层&#xff09; 基本通信流程mac地址和ip地址网络通信本质 网络发展 从一开始计算机作为一台台单机使用&#xff0c;到现在网络飞速发展&#xff0c;从局域网Lan建立起局域网&#xff0…

【零基础学Rust | 基础系列 | Cargo工具】Cargo介绍及使用

文章目录 前言一&#xff0c;Cargo介绍1&#xff0c;Cargo安装2&#xff0c;创建Rust项目2&#xff0c;编译项目&#xff1a;3&#xff0c;运行项目&#xff1a;4&#xff0c;测试项目&#xff1a;5&#xff0c;更新项目的依赖&#xff1a;6&#xff0c;生成项目的文档&#xf…

什么运动耳机好用?市面上公认表现最好的几款耳机

随着技术的发展&#xff0c;运动蓝牙耳机这个类别已经进化到了骨传导的形式&#xff0c;也受到了广大运动爱好者的一致好评。作为爱运动的玩家&#xff0c;我一直在找可以兼顾运动和音质的骨传导&#xff0c;最近体验到了几款表现还不错的无线骨传导耳机&#xff0c;跟大家分享…

JAVASE---继承和多态

继承 比如&#xff0c;狗和猫&#xff0c;它们都是一个动物&#xff0c;有共同的特征&#xff0c;我们就可以把这种特征抽取出来。 像这样把相同的可以重新放到一个类里面&#xff0c;进行调用&#xff0c;这就是继承。 概念 继承(inheritance)机制&#xff1a;是面向对象程…

Java记录一次生产CPU飙升查找原因

java项目:项目定制化产品的微服务,主要做查es的定时任务和报表统计,实时监控数据. 上线几天,cpu报警 看图: 排查思路: 七八个定时任务同时查es,可能造成的飙升,然后只能拿jstack分析,生产环境慎用. jstack是Java开发工具包中的一个命令行工具&#xff0c;用于生成Java虚拟机&…

软件测试环境讲解

在一个项目开发到发布的整个过程中&#xff0c;会使用到很多个环境进行测试和运行项目。最基本的开发环境、测试环境、准生产环境、生成环境 一、开发环境 开发环境顾名思义就是我们程序猿自己把项目放到自己的电脑上&#xff0c;配置好以后&#xff0c;跑起来项目&#xff0c…

高速公路巡检无人机,为何成为公路巡检的主流工具

随着无人机技术的不断发展&#xff0c;无人机越来越多地应用于各个领域。其中&#xff0c;在高速公路领域&#xff0c;高速公路巡检无人机已成为公路巡检的得力助手。高速公路巡检无人机之所以能够成为公路巡检中的主流工具&#xff0c;主要是因为其具备以下三大特性。 一、高速…

stack模拟实现-适配器

在C中&#xff0c;适配器模式常用于对容器类或者容器类的操作进行封装和拓展。std::stack就是一种适配器。它将一个底层容器&#xff08;默认为std::deque&#xff09;的接口转换成了一种先入后出&#xff08;Last-In-First-Out&#xff0c;LIFO&#xff09;的栈的接口。 适配…

SAS-数据集SQL垂直(纵向)合并

一、SQL垂直合并的基本语法 一个selectt对应一个表&#xff0c;select之间用set-operator连接&#xff0c;set-operator包括&#xff1a;except&#xff08;期望&#xff09;、intersect&#xff08;相交&#xff09;、union&#xff08;合并&#xff09;&#xff0c;outer un…

规划路线(微信小程序、H5)

//地图getLocationDian(e1, e2) {console.log(e1, e2);let self this;self.xx1 [];self.xx2 [];self.points [];// self.markers[]console.log(self.markers, >marks);// self.$jsonp(url, data).then(re > {// var coors re.result.routes[0].polyline;// for (v…

2023-08-03 LeetCode每日一题(删除注释)

2023-08-03每日一题 一、题目编号 722. 删除注释二、题目链接 点击跳转到题目位置 三、题目描述 给一个 C 程序&#xff0c;删除程序中的注释。这个程序source是一个数组&#xff0c;其中source[i]表示第 i 行源码。 这表示每行源码由 ‘\n’ 分隔。 在 C 中有两种注释风…