learn C++ NO.16——模板

news2025/1/11 15:08:32

typename关键字

typename是一个c++关键字,主要用于解决模板定义中的依赖类型名称的解析问题。它告诉编译器紧随其后的名称是一个类型,而不是静态成员或成员函数。在模板编程中正确使用typename是理解和编写复杂模板代码的关键。

那什么是模板定义中的依赖类型名称的解析问题?下面我通过一个样例带大家看看。假设我需要写一个遍历容器的打印函数Print()。
在这里插入图片描述

由于在Print函数第一行没有明确的告知编译器Container是对象还是类型。所以,编译器直接报错。解决方法也很简单,就是在Container前加上typername修饰一下,告诉编译器,你大胆实例化,这个模板是类型。然后,编译器就会在实例化的时候去找。

在这里插入图片描述
当然,使用auto关键字也可以解决这样的问题。因为,auto关键字就是类型,它是通过 = 右边的内容去推导类型。
在这里插入图片描述

typename的使用事项

typename只能用于模板定义中,并且紧跟在依赖类型名称之前。

在模板定义之外,当类型已经明确时,不需要使用typename。这也是为什么在前面的学习中没有提到它。

typename不能用于基础类型(如int、float等)或指针类型(如int*)之前,因为这些类型不是依赖于模板参数的。

在模板声明中,即使类型依赖于模板参数,通常也不需要使用typename(但在某些复杂的模板元编程场景中可能会用到)。

在模板声明中,typename和class作为模板类型参数的关键字是等价的,可以互换使用。然而,在指示依赖类型名称时,只能使用typename。

与class的区别

在模板声明中,typename和class作为模板类型参数的关键字是等价的,可以互换使用。然而,在指示依赖类型名称时,只能使用typename。

非类型模板参数

非类型模板参数是一个模板的特性。它允许模板定义时不仅接受类型作为参数,还可以接受常量表达式作为参数。这些常量表达式可以是整型(包括字符、枚举和指针)、引用以及用户定义类型的对象(需要满足常量性和可链接性要求)。

它的出现解决了C语言在对象定义时给定一个常量决定静态数组的长度。
在这里插入图片描述
给静态栈加一个非类型模板参数即可,需要注意的这个常量不能在实例化后被修改。
在这里插入图片描述

array的简单介绍

在这里插入图片描述
array是C++11更新时更新的一个新容器,它就带有非类型模板参数。它的使用逻辑与原生数组以及vector大差不差,这里简单演示一下它的使用。
在这里插入图片描述
它像原生数组那样并不会直接初始化,需要咱们手动初始化。它相较于原生数组提供了更严格的边界检查。这是因为它重载了operator[]。
在这里插入图片描述
整体来说,这个容器还是比较鸡肋。它既不如原生数组贴近底层并且纯粹,又不如vector来的强大。整体还是被吐槽的挺多的。

模板的特化

函数模板特化

函数模板特化是C++泛型编程的一种技术,它帮助我们实现特定类型或一组类型提供函数模板的实现。函数模板的特化只能全特化。下面我就通过一个简单的样例介绍一下它是什么样的。
在这里插入图片描述
需要注意,函数模板的特化必须和原始函数模板在功能上保持逻辑的一致性以及连贯性,避免产生冲突。同时,特化函数模板不能独立于原始函数模板存在。

类模板特化

类模板特化就是对特定类型或一组类型提供类的特殊化实现。具体有全特化和片特化之分。下面先给大家介绍一下语法。

在这里插入图片描述
下面在通过一个样例带大家感受一下特化。在上篇文章中,我们在测试priority_queue对于自定义类型Date的指针处理上,重新实现了仿函数进行控制。现在通过片特化默认的仿函数感受一下。
在这里插入图片描述

在这里插入图片描述
下面简单谈一谈类模板特化的限制。特化模板类必须和原始模板类在同一个命名空间下,并且特化版本和原始版本的模板参数列表和函数形参列表需要一致。

最后,谈一谈类模板特化和函数模板特化的区别。类模板特化是针对整个类进行的,包括成员函数和成员变量。而函数模板特化只能针对特定的数据类型的函数进行特殊化处理,且特殊化版本的形参列表必须和原始版本的一致。

模板分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。

下面以一个场景带大家看看模板的分离编译所产生的问题。
在这里插入图片描述
这里的调试报错报的是链接错误,找不到push、pop函数的地址。
在这里插入图片描述
为了避免这种情况的发生,需要对模板函数定义的位置进行显示实例化。
在这里插入图片描述
当然,对于类模板还是建议声明和定义都放在一个.h或.hpp文件中。尽量避免跨文件使用模板分离编译。同一个文件里声明和定义分离是没啥问题的,像STL库就是这样实现的。

总结

模板的出现大大的增强了编程的灵活性。比如仿函数、适配器等。更重要的是大大增加了代码的复用性,提高了开发的迭代效率,STL库也因为模板的出现孕育而生。再谈一谈模板的缺点。模板的出现延长了编译的时间,当然了不可避免,因为程序员把更多的活给了编译器干。以及模板报错信息又长又乱,非常难以定位错误,这也更考验程序员用经验来解决报错问题。

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

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

相关文章

聚鼎装饰画:做一家装饰画店铺能不能赚钱呢

在当今这个快节奏、高压力的社会环境中,人们越来越渴望在繁忙的生活中找到一丝宁静与美感。装饰画,作为提升居家和办公环境品位的艺术品,其市场需求日益增长。那么,做一家装饰画店铺究竟能不能赚钱呢? 从市场需求的角度来看&…

Codeforces practice /C++ 2024/9/11 - 2024/9/13

D. Mathematical Problem Codeforces Round 954 (Div. 3) 原题链接:https://codeforces.com/contest/1986/problem/D 题目标签分类:brute force,dp,greedy,implementation,math,two pointers…

深度学习经典模型之T5

T5(Text-to-Text Transfer Transformer) 是继BERT之后Google的又外力作,它是一个文本到文本迁移的基于Transformer的NLP模型,通过将 所有任务统一视为一个输入文本并输出到文本(Text-to-Text)中,即将任务嵌入在输入文本中,用文本的…

element ui form 表单出现英文提示的解决方案

场景再现: 在使用 form 表单的时候,一般都需要对表单元素进行验证,错误就出现在了这里,除了配置的错误信息,还会出现一个 英文校验提示,如下图: 解决方案 出现的原因是在el-form-item中使用…

推动数据治理与传统产业深度融合:解锁产业升级新引擎

标题:推动数据治理与传统产业深度融合:解锁产业升级新引擎 在数字化浪潮席卷全球的今天,数据已成为驱动经济社会发展的关键生产要素。传统产业,作为国民经济的基石,正面临着前所未有的变革挑战与转型升级的机遇。数据…

SVN的使用技巧

SVN(Subversion)是近年来崛起的版本管理工具,因为是免费的,所以用的人还是不少的。故做一些总结。 如果是新手,基本对SVN一点都不了解的话,建议去学习一下这个系统的教程,讲的也很详细Tortoise…

腾讯发布大模型安全与伦理报告:以负责任AI引领大模型创新

前言 随着AI模型的能力日益更加强大,如何让其行为和目的跟人类的价值、偏好、伦理原则、真实意图之间实现协调一致,这个被称为人机价值对齐的问题变得越来越重要。价值对齐对于确保人类与人工智能协作过程中的信任与安全至关重要,已经成为AI…

今年的智能手机不仅仅是AI

周一,苹果揭开了其iPhone 16系列的面纱,主要卖点是苹果智能。苹果的设备内AI系统提供了许多引人注目的功能,比如重写电子邮件、生成自定义表情符号和大幅升级的Siri。但在这些表面之下,AI为iPhone带来的还有一个重大变化&#xff…

使用API有效率地管理Dynadot域名,查看域名服务器(NS)信息

前言 Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮箱&…

js 深入理解生成器

目录 概述1 . 生成器基础2. 与普通函数的区别3. 通过 yield 中断执行3.1 yield 是干嘛的?3.2 yield 和 return 的区别3.3 每个生成器对象作用域都是独立的3.4 yeild 的使用位置3.5 生成器对象作为可迭代对象3.6 使用 yield 实现输入和输出3.6.1 yield实现输入3.6.1 …

【原创】java+swing+mysql长途客车售票管理系统设计与实现

个人主页:程序员杨工 个人简介:从事软件开发多年,前后端均有涉猎,具有丰富的开发经验 博客内容:全栈开发,分享Java、Python、Php、小程序、前后端、数据库经验和实战 文末有本人名片,希望和大家…

【双语新闻】 AI 安全新闻 :计算规模的下一代,按越狱敏感性和机器道德对模型进行排名

计算规模的下一代 The Next Generation of Compute Scale AI开发正处在计算规模大幅扩展的边缘。从芯片制造到电力基础设施的最新发展,都指向一个未来,即人工智能模型可能会超过今天最大的系统。在这篇文章中,我们将审视关键的发展以及它们对…

Grafana 汉化

点击 Home -> Administration 点击 Default preferences 点击 中文(简体)后点击 Save 即可

科技感爆棚,智慧票务系统让你的出行超省心

宝子们👋,今天一定要给大家介绍一个超级厉害的东西 —— 智慧票务系统🎉!🎈以前去景区、看演出,排队买票简直是一场噩梦😫,浪费时间不说,还影响心情。但有了智慧票务系统…

52.【C语言】 字符函数和字符串函数(strcat函数)

6.strcat函数 *简单使用 cplusplus的介绍 点我跳转 strcat:string concatenate 字符串连接 *网页翻译 函数 strcat //strcat返回类型char * char * strcat ( char * destination, const char * source ); 连接字符串 对目标(destination)字符串追加源(source)字符串的一个拷…

常用环境部署(二十)——docker部署OpenProject

一、安装Docker及Docker-compose https://blog.csdn.net/wd520521/article/details/112609796 二、docker拉取OpenProject镜像 1、拉取镜像 docker pull openproject/openproject:14 注意: 拉取镜像的时候会有超时的现象出现,大家重新拉取几次就行…

集成电感器TPS82130

集成电感器TPS82130 简介 TPS82130是集成了电感跟0603一样大的BUCK降压模块。输入电压3-17V,输出电压0.9-6V,输出电流3A,0.8V参考电压。 TPS82130属于系统级的封装电源模块,目前价格大概是4.5元。它可以实现100%的占空比&#x…

Leetcode面试经典150题-202.快乐数

题目比较简单,重点是理解思想 解法都在代码里,不懂就留言或者私信 面试的时候可以用我提交的解法,这个更优 class Solution {/**第一种-常规解法,主要的思想是如果出现了循环或者等于1,计算过程就停止如果等于1&…

ClassLoader中各个字段意思

ClassLoader(类加载器)是JVM(Java虚拟机)中一个非常重要的组件,它主要负责将Java类文件(.class文件)加载到JVM的内存中,并对其进行验证、准备、解析和初始化。ClassLoader中的字段就…

vue3+ant design vue动态实现级联菜单~

1、这里使用的是ant design vue 的TreeSelect 树选择来实现的。 <a-form-item name"staffDept" label"责任部门" labelAlign"left"><a-tree-selectv-model:value"formState.staffDept"show-search//允许在下拉框中添加搜索框…