C++初阶 | [十二] 模板进阶

摘要:非类型模板参数,类模板的特化,模板的分离编译,模板总结

前言:C++初阶终篇


1. 非类型模板参数

类型模板参数:如下代码,T 为模板的类型参数。 

#define N 10
template<class T>
class A
{
public:private:T* _a[N];
};void test_1()
{A<int> a1;A<double> a2;
}

非类型模板参数:对于上述代码,如果我们想要对于不同的数据类型创建不同大小的_a数组呢?例如,对于 A<int> 我们可能只要在其中存储10个 int 数据,而 A<double> 我们可能需要在其中存储 100 个 double 类型的数据。所以,对于这样的需求,我们可以在模板中加入非类型模板参数来满足。

template<class T, size_t N>
class A
{
public:private:T* _a[N];
};void test_1()
{A<int, 10> a1;A<double, 100> a2;
}

如上代码,其中的 size_t N 即为模板中的非类型模板参数
对于非类型模板参数有两个要求:(ps. char 也可以,char 也是属于整型家族。另外,C++98只支持整型,C++98之后支持非整型)

(补充) array

std::array
------------------------------------------
template<class T, size_t N> class array;

cplusplus.com/reference/array/array/

array 的意义: 

  • C语言:对于 int a[10];  a[15] = 1; 不会检查越界,a[15] 这个过程本质上是指针解引用
  • C++:对于 array<int ,10> a2; a2[15] = 1; 会检查越界,这里的 a2[15] 本质上是函数调用,所以可以在函数里进行执行越界检查。

C++11初衷是希望大家用这个来代替静态数组,但其实有更好的选择——vector。vector不仅对于越界设置了检查,而且可以按需求进行初始化(array不能按自己需求初始化)


2. 模板的特化

特化:针对某些类型做特殊处理

1)类模板的特化

  • 全特化 

e.g.

上图所展示的即为类模板的全特化,即针对 Data 类中 int 和 char 类型做特殊处理。

#include<iostream>template<class T1, class T2>
class Data
{
public:Data(){std::cout << "Data<T1, T2>" << std::endl;}
private:T1 _d1;T2 _d2;
};template<>
class Data<int, char>
{
public:Data(){std::cout << "Data<int, char>" << std::endl;}
private:int _d1;char _d2;
};void test_2()
{Data<int, int> d1;Data<int, char> d2;
}int main()
{//test_1();test_2();return 0;
}

执行上述代码的结果为:

Data<T1, T2>
Data<int, char>

全特化即是将模板参数列表中所有的参数都确定化。 

  • 偏特化

(也称半特化)

偏特化:任何针对模版参数进一步进行条件限制设计的特化版本。

(针对上述代码所写的 Data 类所举出的例子) 

  1. 方式一:将模板参数类表中的一部分参数特化。

    template<class T1 , class T2>
    class Data
    { …… };


    template<>
    class Data<T1,double>
    { …… };

     
  2. 方式二针对模板参数更进一步的条件限制

    template<class T1 , class T2>
    class Data
    { …… };


    template<>
    class Data<T1*,T2*>
    { …… }; //这里的意思是只要的类型为指针(例如:int* , double* , char* , ……)就调用这个特化出来的 class Data 

2)函数模板的特化 

引入:在 优先级队列 的文章中我们讨论了 对于 priority_queue<Date*> 如何通过仿函数来实现“自定义比较的规则”。这里,我们可以选择通过函数模板的特化来实现。即对 class Less 实现特化。

但是,对于上图所展示的代码,class Less 的成员函数的参数列表按上图的写法会发生传值拷贝,传值拷贝对于自定义类型可能会有深浅拷贝的问题。 因此,参数列表建议改成 cosnt 引用,然而,这同时会给函数模板特化带来一些小问题。

(如果你需要上图的代码↓) 

template<class T>
class Less
{bool operator()(const T& left, const T& right){return left < right;}
};template<>
class Less<Date*>
{bool operator()(Date* const& left, Date* const& right){return *left < *right;}
};

 3)sum.

如果需要,类模板可以使用特化,而函数模板一般不使用特化,更好的选择是实现重载。相当于自己实例化出来一个针对某个数据类型的函数,而自己实例化的这个函数会与函数模板根据类型推导由编译器自动生成的实例化出来的函数构成重载。


3. 模板的分离编译

1)函数模板

2)类模板

类模板的分离编译一般是头文件声明成员(成员变量和成员函数),另外的 .cpp 文件中定义成员函数,以这样的形式分离。同样会产生如函数模板分离编译的链接错误。

3)sum.

如果声明和定义都在一个头文件里,那么预处理展开之后就相当于 调用定义 都在同一个文件里,编译的时候就可以通过调用语句“告诉”编译器通过模板的定义怎样实例化。

(ps.如果非得使模板的声明和定义分离,可以不声明的同时定义,但最好要把声明和定义放在一个文件里)


4. 模板总结

【优点】

1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生;

2. 增强了代码的灵活性。

【缺陷】

1. 模板会导致代码膨胀问题,也会导致编译时间变长;

2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。


END

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

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

相关文章

从开关到模拟量,钡铼IOy系列模块全方位拓展PLC系统的边界

在现代工业自动化系统中&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为控制核心&#xff0c;起着至关重要的作用。而随着工业自动化的不断发展&#xff0c;对于输入/输出&#xff08;IO&#xff09;模块的需求也日益增加&#xff0c;尤其是从简单的开关量到复杂…

统一处理异常和记录日志

统一处理异常 SpringBoot设计&#xff0c;如果出现错误404或500&#xff0c;自动调用特定路径下的html页面(路径和名字都特定)。/templates/error/404.html、/templates/error/500.html。程序中有错误自动就调用该页面。 但是错误有异步请求错误&#xff0c;也想同时记录日志。…

堆:数据结构与应用

文章目录 堆&#xff1a;数据结构与应用堆的概念堆的特点堆的操作调整操作&#xff1a;向上调整&#xff08;AdjustUp&#xff09;删除操作&#xff1a;Pop调整操作&#xff1a;向下调整&#xff08;AdjustDown&#xff09; 堆排序方法一&#xff1a;先建堆后排序方法二&#x…

基于springboot的大创管理系统源码数据库

基于springboot的大创管理系统源码数据库 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了大创管理系统的开发全过程。通过分析大创管理系统管理的不足&#xff0c;创建了一个计算机管理大创管理系统的方案。…

天诚智慧校园管理系统,变革高校物联网锁数智化通行新模式

三月草长莺飞&#xff0c;四月柳绿莺啼&#xff0c;在万物复苏的美好时节&#xff0c;历经半年的精心酝酿与匠心打磨&#xff0c;全场景AIoT解决方案服务商——江苏新巢天诚智能技术有限公司&#xff08;以下简称“天诚”&#xff09;正式推出新一代高校数智化通行管理平台——…

电脑启动引导的两种方式

电脑启动引导的两种方式 电脑启动引导有两种方式&#xff1a;Legacy 传统模式 和 UEFI 新型模式。 一、Legacy&#xff1a;指 主板的 传统的 BIOS 传输模式引导启动加载操作系统。 1.只支持 MBR 分区表&#xff0c;支持 32位和64位操作系统&#xff08;如&#xff1a;winXP&…

JavaEE 初阶篇-深入了解定时器、工厂模式和比较器

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 定时器概述 2.0 实现定时器 2.1 实现定时器 - 定义 MyTask 任务类 2.2 实现定时器 - MyTimer 定时器类存放任务的方法 2.3 实现定时器 - MyTimer 定时器类读取任务…

前端开发攻略---根据音频节奏实时绘制不断变化的波形图。深入剖析如何通过代码实现音频数据的可视化。

1、演示 2、代码分析 逐行解析 JavaScript 代码块&#xff1a; const audioEle document.querySelector(audio) const cvs document.querySelector(canvas) const ctx cvs.getContext(2d)这几行代码首先获取了 <audio> 和 <canvas> 元素的引用&#xff0c;并使用…

群晖虚拟机搭建Synology Drive并实现Obsidian笔记异地多端同步

文章目录 一、简介软件特色演示&#xff1a; 二、使用免费群晖虚拟机搭建群晖Synology Drive服务&#xff0c;实现局域网同步1 安装并设置Synology Drive套件2 局域网内同步文件测试 三、内网穿透群晖Synology Drive&#xff0c;实现异地多端同步Windows 安装 Cpolar步骤&#…

关于学习和技术提升的思考

从技术框架的演进可以看出专业性越来越强&#xff0c;门槛越来越低&#xff0c;我们经常强调要解耦合&#xff0c;把公共模块功能做抽取&#xff0c;减少重复劳动&#xff0c;使主要精力专注于特定场景特定业务的处理。老美在设计框架的时候也是这么干的。殊不知&#xff0c;我…

微服务-4 Nacos

目录 一、注册中心 二、配置管理 1. 添加配置 2. 配置自动刷新 3. 多环境配置共享​编辑 一、注册中心 服务列表&#xff1a; 服务详情&#xff1a; 二、配置管理 1. 添加配置 (1). 在 nacos 界面中添加配置文件&#xff1a; 配置列表&#xff1a; 配置详情&#xff1a;…

2024年华为OD机试真题-符号运算-Python-OD统一考试(C卷)

题目描述: 给定一个表达式,求其分数计算结果 表达式的限制如下: 1. 所有的输入数字皆为正整数(包括0) 2. 仅支持四则运算(+-*/)和括号 3. 结果为整数或分数, 分数必须化为最简格式(比如6, 3/4, 7/8, 90/7) 4. 除数可能为0,如果遇到这种情况,直接输出"ERROR" 5.…

[C++][算法基础]模拟散列表(哈希表)

维护一个集合&#xff0c;支持如下几种操作&#xff1a; I x&#xff0c;插入一个整数 x&#xff1b;Q x&#xff0c;询问整数 x 是否在集合中出现过&#xff1b; 现在要进行 N 次操作&#xff0c;对于每个询问操作输出对应的结果。 输入格式 第一行包含整数 N&#xff0c;…

致远目前最新V8.2,打开公文正文的原文档,提示错误:http返回码=12157……解决办法

新版V8.2&#xff0c;打开发文中的正文原文档时&#xff0c;提示错误&#xff1a;http返回码12157&#xff0c;返回信息安全频道支持出错&#xff0c;更新安装插件也不能解决。 解决办法 设置IE浏览器的Internt选项配置。 控制面板-网络和Internet–Internet选项-高级-使用TLS …

【基础】损失函数和评估指标的区别

文章目录 一.损失函数&#xff08;Loss Function&#xff09;&#xff1a;1.1 作用1.2 示例1.3 常见面试题1.3.1 常见的损失函数有哪些&#xff1f;它们分别适用于什么类型的任务&#xff1f;1.3.2 介绍一下交叉熵损失函数&#xff1f;1.3.3 均方误差损失函数&#xff08;Mean …

如何使用Tomcat+cpolar搭建本地站点并发布到公网分享好友远程访问

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器拥有强大功能&#xff0c;由于其可以实…

【React】React Hooks

useState useState 向组件中添加状态变量 状态是只读的&#xff0c;不可以直接修改 对于对象类型的状态变量&#xff0c;应该传递一个新的对象来更改 需要对象展开&#xff0c;并重新赋值&#xff0c;进行增加或者修改。 如果需要删除&#xff0c;则使用 filter。 import { …

【踩坑日记】Pop!OS中文输入法的坑

文章目录 前言一、编译安装最新的IBus-pinyin输入法1.卸载旧输入法2.安装编译依赖3.下载源码4.编译和安装libpinyin5.编译和安装ibus-libpinyin6.重启IBus服务二、安装Fcitx5前言 使用Linux时,特别是涉及到中文的时候,会遇到一些问题。我最近在使用Pop!OS 22.04,这是Ubuntu…

Qt for MCUs 2.7正式发布

本文翻译自&#xff1a;Qt for MCUs 2.7 released 原文作者&#xff1a;Qt Group高级产品经理Yoann Lopes 翻译&#xff1a;Macsen Wang Qt for MCUs的新版本已发布&#xff0c;为Qt Quick Ultralite引擎带来了新功能&#xff0c;增加了更多MCU平台的支持&#xff0c;并且我们…

Apache SeaTunnel 社区 3 月月报

各位热爱 SeaTunnel 的小伙伴们&#xff0c;SeaTunnel 社区 3 月月报来啦&#xff01;这里将记录 SeaTunnel 社区每个月的重要更新&#xff0c;并评选出月度之星&#xff0c;欢迎关注。 SeaTunnel 月度 Merge Stars 感谢以下小伙伴 3 月为 Apache SeaTunnel 做的精彩贡献&…