C++:模板 II(非类型模板参数,特化,分离编译)

目录

非类型模板参数

模板的特化

函数模板特化

类模板特化 

全特化

偏特化

引用特化

指针特化

模板分离编译


非类型模板参数

什么是非类型模板参数?

顾名思义,它的类型形参并不是一个类型,就是用一个常量来作为类模板或函数模板的一个参数

template<class T, size_t N = 10>
class array
{
public:// ...
private:T _array[N];size_t _size;
};

 上面的这个类模板里就是有一个size_t N,默认是10,代表开10个数组

注意:

1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的

2. 非类型的模板参数必须在编译期就能确定结果

模板的特化

特化是什么?

模板的特化可以说就是模板的特殊化处理

我们通常情况下使用模板可以实现一些与类型无关的代码

但如果有特殊类型可能会得到一些错误的结果,例如:

template<class T>
bool Less(T left, T right)
{return left < right;
}int main()
{cout << Less(1, 2) << endl; // 可以比较,结果正确Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout << Less(d1, d2) << endl; // 可以比较,结果正确Date* p1 = &d1;Date* p2 = &d2;cout << Less(p1, p2) << endl; // 可以比较,结果错误return 0;
}

 这里前面两个都可以比较正确

但是到了最后的Date* p1和p2的比较就会出问题

这时候把p1和p2传进去比较的不是它指向的内容,而是比较的地址,所以这个比较是随机的也是错误的!

函数模板特化

这时候我们就需要特化一个Less函数来支持它的比较

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

函数模板的特化步骤:

1. 首先要有一个基础的函数模板

2. 关键字template后面要有<>

3. 函数名后面跟一个<>,<>中指定需要特化的类型

4. 函数形参的类型必须要和特化的类型相同,如果不同编译器会报错

这时候我们就可以让前面的Date*指针走我们特化的这个函数,结果就正确了

当然我们也可以直接重载Less即可

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 T1, class T2>
class Data
{
public:Data() { cout << "Data<T1, T2>" << endl; }
private:T1 _d1;T2 _d2;
};template <class T1>
class Data<T1, int>
{
public:Data() { cout << "Data<T1, int>" << endl; }
private:T1 _d1;int _d2;
};

偏特化就是有特化,但是没有全部特化

这里就是将第二个参数特化为int,第一个不变,但是要写到特化的<>中

引用特化
template <classT1, class T2>
class Data <T1&, T2&>
{
public:Data(const T1& d1, const T2& d2): _d1(d1), _d2(d2){cout << "Data<T1&, T2&>" << endl;}
private:const T1& _d1;const T2& _d2;
};

这个特化是特化为了引用,所以若是调用的引用类型就会调用到这个模板

Data<int&, int&> d4(1, 2);
指针特化
template <class T1, class T2>
class Data <T1*, T2*>
{
public:Data() { cout << "Data<T1*, T2*>" << endl; }
private:T1 _d1;T2 _d2;
};

 这个特化是特化为了指针,所以若是调用的指针类型就会调用到这个模板

Data<int *, int*> d3;

模板分离编译

若是有如下场景

a.h

template<class T>
T Add(const T& left, const T& right);

a.cpp

template<class T>
T Add(const T& left, const T& right)
{return left + right;
}

main.cpp 

#include"a.h"int main()
{Add(1, 2);Add(1.0, 2.0);return 0;
}

这时候运行就会出现错误

此时的a.cpp形参a.obj,main.cpp形参main.obj

在编译器链接的时候,会将多个合并成一个函数地址链接起来

但是在a.cpp中并没有实例化该Add函数,所以并不会生成具体的Add函数

而在main.cpp中,在链接是并没有找到Add函数的定义(没有被a.cpp实例化),因此链接时报错

解决方法

1. 将声明和定义放到同一个文件下(xxx.hpp或者xxx.h中都可以),比较推荐该方法

2. 模板定义的位置显示实例化(不适用,不推荐)


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

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

相关文章

一款能满足低压供电应用需求SLM8837EF-7G 高效节能的电机驱动芯片

SLM8837EF-7G是一款专为低压供电的电机驱动应用而设计的先进芯片&#xff0c;其内部集成了多种保护电路&#xff0c;以确保系统稳定性和安全性。该芯片拥有双通道 NMOS 半桥输出&#xff0c;分别由两路独立的 PWM 输入控制&#xff0c;提供灵活而精准的控制方式。两个单独的供电…

docker启动ES(elasticsearch:7.17.23)

docker直接启动es&#xff0c;报如下错误 2024-08-22 10:52:27 ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch. 2024-08-22 10:52:27 bootstrap check failure [1] of [1]: the defa…

API接口安全101:基础概念与最佳实践

文章目录 API定义协议架构风格描述语言 Webservicewsdl介绍复现 SOAPswagger介绍指纹查找利用存在目录复现 HTTPWebpack介绍复现 在当今数字化时代,API接口已成为现代软件架构中不可或缺的组成部分。它们连接着各种应用程序和服务,促进了数据交换和功能集成。然而,随着API的普及…

人工智能NLP--特征提取之词嵌入(Word Embedding)

一、前言 在上篇文章中&#xff0c;笔者详细讲解介绍了人工智能自然语言处理特征提取中的TD-IDF型文本处理方法&#xff0c;那么接下来&#xff0c;笔者将为大家揭晓&#xff0c;目前阶段&#xff0c;在特征提取&#xff0c;也就是文本数据转成数字数据领域内最常用也是最好用…

在MAVEN中版本依赖有冲突改怎么处理

1.为什么会出现版本依赖的冲突 如果存在版本冲突&#xff0c;通常可能会引发的报错是ClassNotFoundException、NoSuchMethodError等错误。Maven依赖版本冲突通常是由于间接依赖导致同一个jar包存在多个不同版本。例如&#xff0c;如果B依赖了A的1.0版本&#xff0c;而C依赖了A…

网络安全之xss靶场练习

目录 一、xss靶场练习 1、Ma Spaghet! 2、Jefff 第一个方法 第二个方法 3、Ugandan Knuckles 4、Ricardo Milos 5、Ah Thats Hawt 6、Ligma 7、Mafia​编辑 8、Ok, Boomer 一、xss靶场练习 靶场地址 https://xss.pwnfunction.com/ 页面显示如下 1、Ma Spaghet! 分析…

Python之字符串练习题(下)

21.nameStr“Albert Einstein"&#xff0c;如何使用字符串运算符“:”来提取 nameStr 中的名和姓? mingnameStr[:6] xingnameStr[7:]23.下面哪些语句在运行时不会出错? (a)var xyz ’ * 10.5 (b)var ‘xyz’ * ‘5 ©var‘’xyz’*5 (d)var‘xyz’*5.0 重复运算符…

Flutter Web 正式官宣弃用 HTML renderer , Canvas 路线成为唯一

Flutter Web 团队计划在 2025 年的第一个 Flutter stable 版本中弃用 HTML renderer&#xff0c;当然在 master 和 beta 中会更早合并这一更改。 关于这个话题&#xff0c;其实在年初的我就曾发布过 《Flutter 即将放弃 Html renderer 》&#xff0c; Html renderer 从 2018 年…

Redis远程字典服务器(7)—— set类型详解

目录 一&#xff0c;基本情况 二&#xff0c;常用命令 2.1 sadd 2.2 smembers&#xff0c;sismember 2.3 spop&#xff0c;srandmember 2.3 smove&#xff0c;srem 2.4 sinter&#xff0c;sinterstore求交集 2.5 sunion&#xff0c;sunionstore求并集 2.6 sdiff&#…

MySQ分库分表与MyCat安装配置

目录 介绍 拆分策略 垂直拆分 1. 垂直分库 2. 垂直分表 水平拆分 1. 水平分库‘ 2. 水平分表 实现技术 MyCat概述 安装 概念介绍 MyCat入门 需求 环境准备 分片配置 启动服务 连接测试 执行SQL语句测试 MyCat配置 1. schema.xml 1. schema标签 2. dat…

python | 图片转换为 pdf 实现方法

目录 一、PIL 库简介及安装使用方法 &#xff08;一&#xff09;python 不同版本下 PIL 的使用方法 二、图片转换为 pdf 的两种实现方法 &#xff08;一&#xff09;简易版——pdf 页面尺寸跟随图片大小 &#xff08;二&#xff09;常用版——pdf 每页尺寸统一为 A4 一、P…

C++,std::bind 详解

文章目录 1. 概述2. 基本用法2.1 使用占位符2.2 示例 3. 总结 1. 概述 std::bind 是 C11 引入的一个功能&#xff0c;它允许你将函数&#xff08;或成员函数、函数对象&#xff09;与其参数绑定&#xff0c;生成一个新的可调用对象。这个功能在需要将函数及其参数一起传递给其…

闲鱼IP属地地址:去外地会自动变化吗?解析实时更新机制

在数字化时代&#xff0c;网络交易平台如闲鱼已成为我们日常生活中不可或缺的一部分。在进行二手交易时&#xff0c;了解对方的地理位置信息成为许多买家和卖家的关切点。那么&#xff0c;去外地闲鱼IP会变吗&#xff1f;闲鱼IP属地地址是实时更新吗&#xff1f;本文将深入探讨…

基于百度智能云爆破验证码识别

目录 基于百度智能云爆破验证码识别 一、基于php提供验证码校验接口 二、基于百度云API识别验证码 1、领取资源&#xff0c;创建应用 2、利用应用的API Key和Secret Key获取Access Token 3、文字识别 4、编写爆破程序 基于百度智能云爆破验证码识别 一、基于php提供验证…

华为手机换ip地址怎么换?手机换ip地址有什么影响

在数字化时代&#xff0c;网络已成为我们生活中不可或缺的一部分。无论是日常沟通、工作学习还是娱乐休闲&#xff0c;我们都离不开互联网。然而&#xff0c;随着网络安全问题的日益突出&#xff0c;如何保护个人隐私和信息安全成为了用户关注的焦点。更换手机IP地址作为提升网…

2024年下半年,单独划定的地区报名软考的温馨提示

软考分数线分为全国分数线、省分数线&#xff08;陕西省下半年已取消&#xff0c;仅剩青海省&#xff09;、以及单独划线地区分数线。目前各地2024年下半年软考正在接受报名&#xff0c;请单独划线地区的考生注意——有些地区可能要求考生在考试后进行单独划线申请&#xff0c;…

删除或丢失的移动硬盘数据如何恢复?三种办法助你找回宝贵资料

在数字化时代&#xff0c;移动硬盘已成为我们存储重要数据不可或缺的工具。然而&#xff0c;数据丢失或误删除的情况时有发生&#xff0c;让人倍感焦虑。别担心&#xff0c;本文将为你详细介绍如何恢复删除或丢失的移动硬盘数据&#xff0c;帮助你找回那些宝贵的资料。 一、检…

『 C++ 』IO流

文章目录 IO流概述iostream 的标准对象C流和C标准库I/O函数的同步 sync_with_stdiofstream 文件流文件流的打开标志二进制读写二进制读写的浅拷贝问题文本读写 字符串流注意 IO流概述 流是指数据的有序传输序列,路表示数据从一个地方流向另一个地方的过程,流可以是输入流也可以…

用Python在Ashare获取金融数据官方文档解读

Ashare&#xff0c;也被写作AKShare&#xff0c;是一个基于Python的开源完全免费的财经数据接口库。它的主要目的是为用户提供股票、期货、期权、基金、外汇、债券、指数、加密货币等金融产品的基本面数据、实时和历史行情数据、衍生数据的采集、清洗和落地的一整套工具。AKSha…

算法的学习笔记—把二叉树打印成多行(牛客JZ78)

&#x1f600;前言 在算法面试中&#xff0c;二叉树的层序遍历是一个经典的题目。而这道题的要求是进一步将二叉树的每一层结点值打印成多行&#xff0c;即同一层结点从左至右输出&#xff0c;最终结果存放到一个二维数组中返回。接下来&#xff0c;我们将通过代码实例详细解析…