C++相关概念和易错语法(18)(array、模板)

news2024/9/9 5:59:59

1.array

(1)普通数组的劣势

当我们直接越界修改值时,一般会在编译时就被拦截

但是越界访问,只要访问距离不算特别大,那么也可以越界访问

当我们不直接越界修改或访问,间接去访问和修改能越界非常远

这里的i直到342才被拦截下来,这足以反映出普通的数组是有一定的风险的,在有的情况下会导致数据被篡改,下面以VS编译器为例,在VS中栈区变量由低地址向高地址存,所以向上越界修改会影响其它变量的值,如果这个值很重要,那么使用普通数组就很危险,我们需要一种更安全的方式,这就是array。

(2)array检查方式和普通数组的区别

array是用类封装静态数组,其中类最大的好处是可以重载operator[],可以在重载函数里面添加断言检查等,每一次调用都会进行检查是否越界,如果越界会直接报错。

而普通数组是在数组界外设置了一些标志位,如果标志位被访问或者修改了就会报错,但整体上而言,我们能够进行不同程度上的越界访问和修改,依然有风险,就像上面展示的那样。

当我们使用array时,就能很好地避免这个问题。

但是arrary不如使用vector,因为在处理上和vector几乎没什么区别,但array是在栈区开辟,而vector是在堆区开辟空间,堆区的空间要远远大于栈区的空间。所以推荐使用vector,其相较于普通数组的优势和array的一模一样。

2.非类型模板参数

定义模板时要传模板参数,其中有类型模板参数,如class T参数接受的就是一个类型(如int、double),类型模板参数实施例化出函数或类的关键,也是模板的精髓所在。但除此之外,在模板参数处还可以定义非类型模板参数,如int a,char b接收的就是值而非类型。

利用非类型模板参数定义的是常量而不是变量,不能有任何修改操作

非类型模板参数在C++20前只能是整型家族的,如char、size_t、int等,而指针、double类型是不支持的

切换到C++20,就可以使用内置类型作为非类型模板参数了,包括内置类型的指针、double等

设置界面如下:

但是需要注意的是,C++20后仍不支持自定义类型作为非类型模板参数,像string这些都不支持

3.模板的按需实例化

模板有个特点是按需实例化,在我们没有调用这个模板类或模板函数时,它是不会实例化的。这意味着编译器只会检查最基本的语法错误,而不会去检查里面的细节

(1)普通函数和模板的检查严格程度的比较

我们来对比一下

对于普通函数,就算我们不去调用它,编译器在编译阶段是会比较深入的去检查的,这里由于"a"是常量字符串,不能修改,所以交给arr的指针不能*arr,因此要用const char*,所以报错了。这里同时也要注意1和3是有区别的,3是单独在栈区开了一块空间,所以不会报错,而1并没有开空间。

而对于模板来说,编译器的检查就很弱了。

在这里我们可以看到,char* arr = "a"本身就是个错误写法但没有报错。包括Fun()里面的N++也是经典的语法错误,但这些在编译阶段都不会被检查出来,只有在触发了很离谱的语法错误(忘写分号等)才会检查出来,而且这个时候的报错极为难看。

记住下面这种报错原因,等会有用

只有当实例化后我们才能检查到错误,就算类被实例化了,如果里面有模板函数,在被调用前这些模板函数也不会实例化,这就是按需实例化。

(2)typename声明

刚刚第二张模板类报错是因为arr b = "a"犯了严重的语法错误。即arr不是类型。看上去这个错误很荒谬,但是这引出了一个新的问题,如下图:

究竟是什么导致了错误,我们已经知道,模板类实例化之前检查语法很弱,但这里就有一个显然的语法错误,那就是Test<T>::iterator it中iterator究竟是静态成员变量还是一个类型呢?

这就跟我最开始提到的arr b = "a"出现了同样的问题,为了避免歧义,我们需要在最前面声明它是一个类型而非静态成员函数。

但是这里需要注意的是这是在模板的前提下才需要这么写,如果已经实例化出了Test<int>,这种语法就不会导致歧义,编译器能很轻松的判断这是一个类型

4.特化

(1)全特化

函数模板的特化和类模板的特化用法上都很好理解,实际就是针对一些很特殊的类型做特殊的处理,注意要写template<>,这其实是声明这是个模板,没有模板参数就不写,在函数名或类名后要写实例化的类型。

但这里需要特别注意的是全特化指针或引用时,要注意全特化的函数的传参要和模板函数的参数匹配

下面这种写法为什么有问题?

原因在于const T中const修饰的是ptr,即ptr不能修改,同理,ref也不能修改。而const int*的意思是*ptr而不是ptr本身,ref也是如此,所以const的位置要变,下面这种才是正确写法

在优先级上,如果已经定义了普通函数,就会最优先调用普通函数,其次找特化,如果实在没有,就会去实例化模板函数。一般来说特化用的不多,因为像刚才那样的坑很难理解,所以如果真要特殊处理,直接写普通函数是最好的选择。

(2)偏特化(只能针对类)

偏特化(半特化)是针对某一个模板参数而非全部模板参数进行特殊化处理。针对的方式可以是类型,也可以是某种修饰,如*、&等

先介绍一个简单的,就是针对某一个或几个而非全部模板参数的特殊处理。在写法上和全特化很像,我们可以认为全特化是偏特化的一种特殊情况。

但是注意偏特化不能针对函数,只能在类上使用偏特化

偏特化中还有一种就是针对某种修饰方式进行特殊处理

看下面这段代码


#include <iostream>
using namespace std;

template<class T1, class T2>
class test
{
public:
	test()
	{
		cout << "test" << endl;
	}
};

template<class T1, class T2>
class test<T1*, T2&>
{
public:
	test()
	{
		cout << "T1 = " << typeid(T1).name() <<  endl << "T2 = " << typeid(T2).name() << endl;
	}
};

int main()
{

	test<int, char>();
	test<int*, int&>();

	return 0;
}

我们发现当实例化是加上*或者&时,当实例化类型对上时就会走偏特化。而对于T1和T2而言还能反推。

需要注意的是,const也可作为修饰成分并严格要求匹配才会调用偏特化


偏特化的好处在于能针对处理的类型更灵活,并且通过修饰的类型能推导原类型,我们又可以通过这个原类型加一些修饰得到其它修饰的类型,在代码中选择更多。

5.编译模板

模板是不能声明和定义分到两个文件中的。

原因在于如果对于普通函数,虽然声明定义分离,但是定义处的函数代码仍然完整,可以顺利编译,链接时进符号表,如果声明定义没有分离,那在编译阶段就能进符号表。当调用函数时,会直接到符号表中找,效率很高。

但对于模板函数编译器是不会编译的,因为不知道编译成什么。如果让模板去遍历文件找实例化,大型项目文件多的情况效率大大降低,不会这么做。当编译器遇到调用模板函数时,就会实例化声明,但这个声明找不到定义,定义处直接被跳过编译了。而如果在同一文件或在定义处显式声明实例化类型,就能在第一时间实例化。

总结一下:唯一的方案是模板不要分离文件,声明处知道实例化成什么但没定义,定义处有定义但不知道实例化成什么

6.模板缺陷:编译时间变长,错误信息凌乱

7...cc就是.cpp,而.hpp是.cpp和.h结合,根据模板的性质,我们可以将模板写在.hpp文件中

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

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

相关文章

AWS认证考试流程:从准备到通过

AWS认证是IT行业中备受推崇的专业资格认证之一&#xff0c;它不仅可以验证您的AWS技能&#xff0c;还能提升您的职业竞争力。本文将为您详细介绍AWS认证考试的完整流程&#xff0c;从初步准备到最终通过认证。 选择适合的认证级别 AWS提供多个级别的认证&#xff0c;包括&…

Java中的LinkedList(链表)(如果想知道Java中有关LinkedList的知识点,那么只看这一篇就足够了!)

前言&#xff1a;在Java编程语言中&#xff0c;Java集合框架提供了一组丰富的数据结构&#xff0c;以满足各种应用需求。其中&#xff0c;LinkedList作为一种常用的数据结构&#xff0c;具有独特的优势和广泛的应用场景。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内…

MesooRF:经典蓝牙模块与低功耗蓝牙模块如何区分?

从蓝牙4.0开始&#xff0c;有两种蓝牙芯片模块&#xff1a;经典蓝牙模块(BT)和低能耗(BLE)蓝牙模块。 经典蓝牙是在之前的蓝牙1.0&#xff0c;1.2&#xff0c;EDR 2.0&#xff0c;EDR 2.1&#xff0c;EDR 3.0的基础上发展完善的&#xff0c;而低功耗蓝牙是在Nokia的Wibree标准上…

客户关系管理怎么做?这4个工具一定要会用!

在商海浮沉中&#xff0c;每一位企业家和销售经理都深知&#xff0c;客户是企业生存与发展的基石。但如何有效管理这些宝贵的资源&#xff0c;让每一次互动都成为加深关系、促进成交的契机&#xff0c;却是一门艺术加科学的结合体。今天&#xff0c;咱们就来聊聊客户关系管理&a…

79. UE5 RPG 创建技能冷却和消耗

在这一篇里面&#xff0c;我们接着优化技能&#xff0c;现在角色添加的主动技能能够同步到ui上面。我们在这一篇文章里面&#xff0c;完善技能的消耗&#xff08;释放技能减少蓝量&#xff09;和冷却机制。 我们可以看到&#xff0c;在技能类默认值这里&#xff0c;可以设置它的…

AIGC时代创意设计师从“创作”向“智作”升级

随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;AI Generated Content&#xff0c;即人工智能生成内容&#xff09;时代已经到来&#xff0c;为创意设计领域带来了前所未有的变革。在这一时代背景下&#xff0c;创意设计师们正经历着从传统的“创作”向“智作”的转型…

SCSA第五天

NAT 静态NAT 动态NAT Napt 一对多 --- easy ip 多对多的NAPT 服务器映射 源NAT --- 基于源IP地址进行转换&#xff0c;包含静态NAT&#xff0c;动态NAT以及NAPT 目标NAT --- 基于目标IP地址进行转换&#xff0c;以前的端口映射 双向NAT --- 同时转换源IP地址和目标IP地…

SpringSecurity中文文档(Servlet Authorization Architecture )

Authorization 在确定了用户将如何进行身份验证之后&#xff0c;还需要配置应用程序的授权规则。 Spring Security 中的高级授权功能是其受欢迎的最有说服力的原因之一。无论您选择如何进行身份验证(无论是使用 Spring Security 提供的机制和提供者&#xff0c;还是与容器或其…

Point Cloud Library (PCL) for Python - pclpy 安装指南

以下所有的版本号务必按照说明安装。 1.安装 Python 3.6 https://www.python.org/ftp/python/3.6.8/python-3.6.8-amd64.exe #或 百度网盘 2.确认 Python 版本为 3.6.x python #Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on…

BUUCTF[堆][unsortbin]

fastbin Attack 、unsorted bin 思路&#xff1a; 利用double free的方式泄漏出unsortbin中的main_arena地址。 释放一个不属于fast bin 的 chunk&#xff0c;并且该 chunk 不和 top chunk 紧邻时&#xff0c;该 chunk 会被首先放到 unsorted bin 中。 当有一个(或几个) sma…

问题清除指南|Dell OptiPlex 7070 升级 win11 开启 TPM 2.0 教程

前言&#xff1a;最近想把实验室台式机的系统从 Windows 10 升级到 Windows 11&#xff0c;遇到一点小问题&#xff0c;在此记录一下解决办法。 ⚠️ 注&#xff1a;本教程仅在 Dell OptiPlex 7070 台式机系统中测试有效&#xff0c;并不保证其余型号机器适用此教程。 参考链接…

不同材质酒店智能开关的功能特点详解

在当今的酒店行业中&#xff0c;智能开关已成为提升客户体验和管理效率的重要设备。而不同材质的智能开关&#xff0c;不仅在外观上各具特色&#xff0c;其功能特点也有所差异。 玻璃材质智能开关&#xff1a; 玻璃材质的智能开关给人一种时尚、简约且高端的感觉。其表面光滑&a…

Iridient Developer:解锁Mac RAW图像处理的极致潜力,打造专业级色彩与细节

Iridient Developer for Mac是一款专为Mac用户设计的RAW图像调整软件&#xff0c;它以其卓越的性能和丰富的功能&#xff0c;赢得了众多摄影师的青睐。以下是对这款软件的详细介绍&#xff1a; 一、强大的RAW图像处理能力 Iridient Developer专为处理RAW图像而设计&#xff0…

连锁行业观察:一线门店设备如何运维?化“管理”为“服务”

连锁零售行业的数字化发展&#xff0c;离开不了大量智能设备的支撑&#xff0c;比如我们日常见到的各种门店互动终端、自助收银设备、无人值守售货机等等。 由于连锁行业的特性&#xff0c;这些设备往往位置分散&#xff0c;数量众多&#xff0c;难以集中管理。一旦这些设备遇…

48、DR+keepalive

DRkeepalive 注意vrrp_iptables:##不创建iptables策略 keepalive的脑裂问题怎么解决&#xff1f; DRkeepalive解决主服务器挂了&#xff0c;备服务器立即进入工作。 DRkeepalive思路 主调度器&#xff1a;test1&#xff1a;192.168.168.100副调度器&#xff1a;test2&#…

渲染100农场是什么?渲染100邀请码1a12

作为设计师&#xff0c;渲染农场肯定听过&#xff0c;它在视觉行业有着重要作用&#xff0c;那么渲染农场是什么您知道吗&#xff1f;今天我们就来看看吧。 渲染农场&#xff0c;英文名Render Farm&#xff0c;是一种分布式并行计算系统&#xff0c;是利用现成的以太网、CPU和…

网上下载的视频怎么转成mp4格式?教你一招轻松解决

网上拥有许多的视频资源&#xff0c;动漫&#xff0c;短视频&#xff0c;影视等等都层出不穷&#xff0c;很多小伙伴都会把一些视频进行下载下来&#xff0c;不过下载下来的视频都不是MP4格式的&#xff0c;在兼容性方面会比较的麻烦&#xff0c;会有播放器不支持的情况&#x…

【MySQL】mysqldumpslow工具 -- 总结慢查询日志文件

1. 作用 在平时使用MySQL数据库时&#xff0c;经常进行查询操作&#xff0c;有些查询语句执行的时间非常长&#xff0c;当执行时间超过设定的阈值时&#xff0c;我们称这个查询为慢查询&#xff0c;慢查询的相关信息通常需要用日志记录下来称为慢查询日志&#xff0c;mysqldum…

java项目中与客户对接接口

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

德国哥廷根大学《Nature Geoscience》最新成果!揭示热带森林对季节性干旱的响应机制!

本文首发于“生态学者”微信公众号&#xff01; 越来越多的研究称热带森林的生产力受到养分限制&#xff0c;这可能影响其对季节性干旱的反应&#xff08;Nature正刊&#xff01;亚利桑那大学 博士生陈舒立一作兼通讯 最新重磅成果&#xff01;&#xff1b;《Nature Geoscience…