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;也想同时记录日志。…

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

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

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步骤&#…

微服务-4 Nacos

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

[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 …

如何使用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 做的精彩贡献&…

【个人使用分享】教你大厂云服务器如何选 联机不卡顿 幻兽帕鲁小白一键部署 16G低至26 续费1.5折

更新日期&#xff1a;4月11日&#xff08;半年档 价格回调&#xff0c;京东云采购季持续进行&#xff09; 本文纯原创&#xff0c;侵权必究 《最新对比表》已更新在文章头部—腾讯云文档&#xff0c;文章具有时效性&#xff0c;请以腾讯文档为准&#xff01; 【腾讯文档实时更…

计算机网络——WEB服务器编程实验

实验目的 1. 处理一个 http 请求 2. 接收并解析 http 请求 3. 从服务器文件系统中获得被请求的文件 4. 创建一个包括被请求的文件的 http 响应信息 5. 直接发送该信息到客户端 具体内容 一、C 程序来实现 web 服务器功能。 二、用 HTML 语言编写两个 HTML文件&#xff0c;并…

面向对象设计原则实验“依赖倒置原则”

高层模块不应该依赖于低层模块。二者都应该依赖于抽象。抽象不应该依赖于细节。细节应该依赖于抽象。 &#xff08;开闭原则、里氏代换原则和依赖倒转原则的三个实例很相似&#xff0c;原因是它之间的关系很紧密&#xff0c;在实现很多重构时通常需要同时使用这三个原则。开闭…

【RealSense】Ubuntu20.04 安装 Intel RealSense ROS 并使用 D435i 测试

【RealSense】Ubuntu20.04 安装 Intel RealSense ROS 并使用 D435i 测试 1 本机环境2 安装流程3 存在的 bug3.1 Resource not found: rgbd_launch 1 本机环境 Ubuntu20.04ROS Noetic 2 安装流程 参考文档: Link 安装 Intel RealSense™ SDK 2.0&#xff0c;参考上一篇文章: L…

『研学倒计时』日本《极致产品力》顾问式研学再出发!

信心行动》共建中国食品行业风向标 2024年,信心比黄金还重要! 深度学习日本就是最佳路线。过去五年,许多中国企业开始研究与借鉴日本,元气森林、东方树叶、奈雪的茶、RIO鸡尾酒、蒟蒻果冻、丸美美妆、花印、名创优品.….从日本“失去的20年”中吸收逆势增长经验。 一、研学背…

快速列表quicklist

目录 为什么使用快速列表quicklist 对比双向链表 对比压缩列表ziplist quicklist结构 节点结构quicklistNode quicklist 管理ziplist信息的结构quicklistEntry 迭代器结构quicklistIter quicklist的API 1.创建快速列表 2.创建快速列表节点 3.头插quicklistPushHead …