当前位置: 首页 > news >正文

【C++】学习笔记——模板进阶

文章目录

  • 十一、模板进阶
    • 1. 非类型模板参数
    • 2. 按需实例化
    • 3. 模板的特化
      • 类模板的特化
    • 4. 模板的分离编译
  • 未完待续


十一、模板进阶

1. 非类型模板参数

模板参数分为类型形参和非类型形参类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

// 第一个形参为类型形参,第二个缺省形参为非类型形参
template<class T, size_t N = 10>
#include<iostream>
using namespace std;template<class T, size_t N>
class arr
{// N可以用来分配初始空间
};int main()
{arr<int, 10> a1;arr<int, 1000> a2;return 0;
}

在C++20之前,只支持整形做非类型模板参数

2. 按需实例化

类模板在实例化这个类的时候,会按需实例化(调用了哪个成员函数就实例化哪个函数) 。

#include<iostream>
using namespace std;template<class T, size_t N>
class arr
{
public:T& operator[](size_t index){// 该函数参数不匹配size(1);return _array[index];}const T& operator[](size_t index)const{return _array[index];}size_t size()const { return _size; }bool empty()const { return 0 == _size; }private:T _array[N];size_t _size;
};int main()
{// 不去调用 operator[] 时,检查不出来错误arr<int, 10> a1;arr<int, 1000> a2;return 0;
}

在这里插入图片描述
当调用出错的部分的函数时才能检查出错误:

int main()
{// 不去调用 operator[] 时,检查不出来错误arr<int, 10> a1;arr<int, 1000> a2;// 调用operator[]a1[1];return 0;
}

在这里插入图片描述

3. 模板的特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果。比如说我们有这样一个函数模板:

template<class T>
bool less(T left, T right)
{return left < right;
}

该函数模板可以比较大小,但是假如有人错误的传入 地址 当实参,这里必然会出现不确定的结果。如果我们想要传地址也让其结果正确的话,我们就可以使用 模板的特化 。特化就是将模板特殊化,在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。即新增一个特化后的模板。

#include<iostream>
using namespace std;// 函数模板
template<class T>
bool Less(T left, T right)
{return left < right;
}// 特化后的模板
template<>
bool Less<int*>(int* left, int* right)
{return left < right;
}

此时,要是实例化的参数更符合特化就使用特化模板进行实例化,否则使用普通的函数模板进行实例化。

函数模板的特化步骤:

  1. 必须要先有一个基础的函数模板
  2. 关键字template后面接一对空的尖括号<>
  3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
  4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。

一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出,即直接实现一个特殊的函数构成重载。

bool Less(Date* left, Date* right)
{return *left < *right;
}

该种实现简单明了,代码的可读性高,容易书写,因此函数模板不建议特化。

类模板的特化

类模板特化也分为 全特化偏特化
全特化即是将模板参数列表中所有的参数都确定化。偏特化是任何针对模版参数进一步进行条件限制设计的特化版本

template<class T1, class T2>
class Data
{
public:Data(){cout << "Data<T1, T2>" << endl;}
private:T1 _d1;T2 _d2;
};// 全特化
template<>
class Data<int, char>   // 参数都全部给定
{
public:Data(){cout << "Data<int, char>" << endl;}
private:int _d1;char _d2;
};// 半特化/偏特化
template<class T>
class Data<T, char>     // 不是全特化的特化
{
public:Data(){cout << "Data<T, char>" << endl;}
private:int _d1;char _d2;
};

类模板的偏特化还可以这样使用:

//两个参数偏特化为指针类型 
template <class T1, class T2>
class Data<T1*, T2*>
{
public:Data(){cout << "Data<T1*, T2*>" << endl;}
private:T1 _d1;T2 _d2;
};

偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本

4. 模板的分离编译

模板不建议声明和定义分离 。当声明和定义分离时,声明处有调用,所以知道模板实例化的类型,但是没有实现功能,定义处没有调用,可以实现功能但是不知道实例化的类型,所以定义处在编译时,并不会生成地址,导致链接时找不到地址从而产生链接错误。

在这里插入图片描述
解决方法有两种:①模板定义的位置显式实例化。(这种方法不实用,不推荐使用)②不进行声明和定义分离,将定义也放在.h头文件里


未完待续

相关文章:

【C++】学习笔记——模板进阶

文章目录 十一、模板进阶1. 非类型模板参数2. 按需实例化3. 模板的特化类模板的特化 4. 模板的分离编译 未完待续 十一、模板进阶 1. 非类型模板参数 模板参数分为类型形参和非类型形参 。类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的…...

JAVA系列 小白入门参考资料 接口

目录 接口 接口的概念 语法 接口使用 接口实现用例 接口特性 实现多个接口和实现用例 接口间的继承 接口 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本上的 USB 口&#xff0c;电源插座等。 电脑的 USB 口上&am…...

日报表定时任务优化历程

报表需求背景 报表是一个很常见的需求&#xff0c;在项目中后期往往会需要加多种维度的一些统计信息&#xff0c;今天就来谈谈上线近10个月后的一次报表优化优化之路&#xff08;从一天报表跑需要五分钟&#xff0c;优化至秒级&#xff09; 需求&#xff1a;对代理商进行日统计…...

excel表格里,可以把百分号放在数字前面吗?

在有些版本里是可以的&#xff0c;这样做&#xff1a; 选中数据&#xff0c;鼠标右键&#xff0c;点击设置单元格格式&#xff0c;切换到自定义&#xff0c;在右侧栏输入%0&#xff0c;点击确定就可以了。 这样设置的好处是&#xff0c;它仍旧是数值&#xff0c;并且数值大小没…...

应用案例 | 商业电气承包商借助Softing NetXpert XG2节省网络验证时间

一家提供全方位服务的电气承包商通过使用Softing NetXpert XG2顺利完成了此次工作任务——简化了故障排查的同时&#xff0c;还在很大程度上减少了不必要的售后回访。 对已经安装好的光纤或铜缆以太网网络进行认证测试可能会面临不同的挑战&#xff0c;这具体取决于网络的规模、…...

【JAVA语言-第20话】多线程详细解析(二)——线程安全,非线程安全的集合转换成线程安全

目录 线程安全 1.1 概述 1.2 案例分析 1.3 解决线程安全问题 1.3.1 使用synchronized关键字 1.3.1.1 同步代码块 1.3.1.2 同步方法 1.3.2 使用Lock锁 1.3.2.1 概述 代码示例&#xff1a; 1.4 线程安全的类 1.4.1 非线程安全集合转换成线程安全集合 1.5 总结 …...

区块链中的加密算法及其作用

区块链技术以其去中心化、不可篡改、透明公开的特性&#xff0c;在全球范围内引发了广泛的关注和讨论。其中&#xff0c;加密算法作为区块链技术的核心组成部分&#xff0c;对于维护区块链网络的安全、确保数据的完整性和真实性起到了至关重要的作用。本文将详细介绍区块链中常…...

微信小程序跳转微信管理平台配置的客服及意见页面

<button open-type"contact" bindcontact"handleContact" session-from"sessionFrom">帮助与客服</button> 不需要路径 在当前小程序中会自动进入 open-type"contact" 其他参数不用修改 只修改这个参数对应表单组件 /…...

灌溉机器人 状压dp

灌溉机器人 题目描述 农田灌溉是一项十分费体力的农活&#xff0c;特别是大型的农田。小明想为农民伯伯们减轻农作负担&#xff0c;最近在研究一款高科技——灌溉机器人。它可以在远程电脑控制下&#xff0c;给农田里的作物进行灌溉。 现在有一片 N 行 M 列的农田。农田的土…...

用于接收参数的几个注解

了解四种主要请求方法的传参格式 GET方法&#xff1a; 参数通常通过URL的查询字符串&#xff08;query string&#xff09;传递&#xff0c;形式为key1value1&key2value2。示例&#xff1a;http://example.com/api/resource?key1value1&key2value2 POST方法&#xf…...

Flask-Login 实现用户认证

Flask-Login 实现用户认证 Flask-Login 是什么 Flask-Login 是 Flask 中的一个第三方库&#xff0c;用于处理用户认证和管理用户会话&#xff0c;它提供了一组工具和功能&#xff0c;使得在 Flask 应用程序中实现用户认证变得更加简单和方便。 如何使用 Flask-Login 1.安装…...

基于WPF的DynamicDataDisplay曲线显示

一、DynamicDataDisplay下载和引用 1.新建项目&#xff0c;下载DynamicDataDisplay引用&#xff1a; 如下图&#xff1a; 二、前端开发&#xff1a; <Border Grid.Row"0" Grid.Column"2" BorderBrush"Purple" BorderThickness"1"…...

股票问题(至多两次购买

class Solution {public int maxProfit(int[] prices) {int[] dpnew int[4];dp[0]-prices[0];//第一次持有dp[1]0;dp[2]-prices[0];//第二次持有dp[3]0;for(int i1;i<prices.length;i){dp[0]Math.max(dp[0],-prices[i]);dp[1]Math.max(dp[1],dp[0]prices[i]);dp[2]Math.max(…...

车辆运动模型中LQR代码实现

一、前言 最近看到关于架构和算法两者关系的一个描述&#xff0c;我觉得非常认同&#xff0c;分享给大家。 1、好架构起到两个作用&#xff1a;合理的分解功能、合理的适配算法&#xff1b; 2、好的架构是好的功能的必要条件&#xff0c;不是充分条件&#xff0c;一味追求架构…...

Springboot集成feign远程调用

需求&#xff1a;在leadnews-wemedia微服务里需要调用leadnews-article微服务的接口。新建一个支持feign调用的名为heima-leadnews-feign-api的模块 heima-leadnews-feign-api的pom文件里导入openfeign依赖 <dependency><groupId>org.springframework.cloud</g…...

构建NFS远程共享存储

nfs-server:10.1.59.237 nfs-web:10..159.218 centos7,服务端和客户端都关闭防火墙和selinux内核防火墙&#xff0c;如果公司要求开启防火墙&#xff0c;那需要放行几个端口 firewall-cmd --add-port2049/tcp --permanent firewall-cmd --add-port111/tcp --permanent firew…...

X9C103SIZT1 数字电位计 IC 10K SOIC-8 参数 应用案例

X9C103SIZT1 是一款数字电位器&#xff0c;属于 X9C103 系列。它是一款100抽头的非易失性数字电位器&#xff0c;阻值为 10 kOhm&#xff0c;封装形式为 SOIC-8。这款器件常用于需要调整电子设备阻值的应用中&#xff0c;如音频设备、电源管理以及传感器校准等。 X9C103SIZT1 的…...

redis深入理解之数据存储

1、redis为什么快 1&#xff09;Redis是单线程执行&#xff0c;在执行时顺序执行 redis单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时包括获取(socket 读)、解析、执行、内容返回 (socket 写)等都由一个顺序串行的主线…...

用20行python写一个最简单的网站

先安装flask框架&#xff0c;cmd命令行 pip install flask&#xff0c;或pycharm -> setting -> project -> python interpreter 搜索安装 # 引入Flask框架 from flask import Flask# 实例化Flask应用 app Flask(__name__)# 定义一个路由&#xff0c;当用户访问网站…...

零基础入门篇①③ Python可变序列类型--列表

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏限时一个月(5.8~6.8)重…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...

raid存储技术

1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划&#xff0c;涵盖存储系统的布局、数据存储策略等&#xff0c;它明确数据如何存储、管理与访问&#xff0c;为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...