C++模板扩展

目录

1.非类型模板参数

2.模板的特化


1.非类型模板参数

        我们知道,模板一般是不指定类型的,具体是什么类型由其他部分的代码的决定。

        模板参数分为类型模板参数和非类型模板参数。

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

        

// 定义一个模板类型的静态数组template<class T, size_t N = 10>class array{public:T& operator[](size_t index){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;};

        浮点数、类对象以及字符串是不允许作为非类型模板参数的。C++20目前似乎支持。

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;
}

         错误的原因就是因为这里比较的是地址的大小。要想避免这种情况发生,对模板特化。

// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{return left < right;
}
// 对Less函数模板进行特化
template<>
bool Less<Date*>(Date* left, Date* 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;
}

        但一般都是直接给出这个函数。

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;
};
void TestVector()
{Data<int, int> d1;Data<int, char> d2;
}

        第二种情况称为偏特化,也有的说法叫半特化,这种用法挺有意思的。

        先来看看普通的偏特化:

 

template<class T1, class T2>
class Data
{
public:Data() {cout<<"Data<T1, T2>" <<endl;}
private:T1 _d1;T2 _d2;
};
// 将第二个参数特化为int
template <class T1>
class Data<T1, int>
{
public:Data() {cout<<"Data<T1, int>" <<endl;}
private:T1 _d1;int _d2;
}; 

        这种情况大家都容易想到,来看看下面这种,挺有意思的

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

比如:

#include<vector>
#include <algorithm>
template<class T>
struct Less
{bool operator()(const T& x, const T& y) const{return x < y;}
};
int main()
{Date d1(2022, 7, 7);Date d2(2022, 7, 6);Date d3(2022, 7, 8);vector<Date> v1;v1.push_back(d1);v1.push_back(d2);v1.push_back(d3);// 可以直接排序,结果是日期升序sort(v1.begin(), v1.end(), Less<Date>());vector<Date*> v2;v2.push_back(&d1);v2.push_back(&d2);v2.push_back(&d3);// 可以直接排序,结果错误日期还不是升序,而v2中放的地址是升序// 此处需要在排序过程中,让sort比较v2中存放地址指向的日期对象// 但是走Less模板,sort在排序时实际比较的是v2中指针的地址,因此无法达到预期sort(v2.begin(), v2.end(), Less<Date*>());return 0;
}

 全特化后:

// 对Less类模板按照指针方式特化
template<>
struct Less<Date*>
{bool operator()(Date* x, Date* y) const{return *x < *y;}
};

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

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

相关文章

Redis保证数据一致性-延时双删代码实现

Redis和数据库的数据一致性在某些场景下非常重要&#xff0c;如何最大程度保证Reids和数据库之间的数据一致呢&#xff1f; 想必大家第一时间会想到延时双删策略&#xff1a; 在修改数据库之前删除缓存&#xff0c;然后数据库中的数据修改完成后&#xff0c;再过一段时间再删…

APP2:android studio如何使用lombok

一、前言 不知道从哪个版本开始&#xff0c;android studio便无法在plugins中下载lombok了&#xff0c;有人说是内置了&#xff0c;好像有这么回事儿。我主要面临如下两个问题&#xff1a; 使用内置lombok&#xff0c;可以自动生成setter、setter、toString等。但是&#xff0…

mediapipe 实现姿态分析——举手检测

目录 人体姿态检测 效果展示 举手检测 行业应用 代码实现 代码分析 效果展示 代码修改&#xff0c;一只手举起即可 总结 啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦^_^啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦♪(^∇^*)啦啦啦…

踏上Python之旅:从零开始,全面解析Python安装与环境配置的必知必会

在踏入Python编程殿堂之前,首当其冲的任务就是正确安装并配置Python开发环境。本文将引导您掌握Python的安装过程、不同操作系统下的最佳实践,以及如何进行多版本管理和虚拟环境设置,为您的Python开发之路打下坚实基础。 一、Python安装 Windows系统: 访问官网下载: 打开…

休息日的思考与额外题——纯纯暴力day42

文章目录 前言动态规知识点 动规五部曲一、100233. 重新分装苹果二、100247. 幸福值最大化的选择方案总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划二刷完卡子哥的刷题计划&#xff0c;加油&#xff01; 二刷决定精刷了&#xff0c;于是参加了卡子…

Linux 自动检测进程是否存活,如果挂掉自动拉起

以 jupyter 服务为例 1、检测脚本 vim /home/ailab/bin/check_ailab.sh #!/bin/bashPID$(ps -ef|grep -v grep|grep "jupyter" |awk {print $2})# 检查进程是否存在 if [ -z "$PID" ]; then# 进程不存在&#xff0c;启动进程echo "Jupyter Noteboo…

使用Vue.js开发前端项目

Vue.js是一个非常受欢迎的渐进式JavaScript框架&#xff0c;用于开发强大而互动的前端应用程序。Vue易于上手&#xff0c;同时拥有强大的功能库和灵活的生态系统。在本篇博客中&#xff0c;我将带你了解使用Vue.js开发项目的基本步骤&#xff0c;并提供相应的代码示例。 环境安…

自由职业者如何在Fiverr兼职赚美金

在这个忙碌的时代&#xff0c;大家都渴望在业余时间找到一份兼职&#xff0c;为自己带来额外的收入。然而&#xff0c;很多人常常感到困惑&#xff0c;不知道如何找到一份既赚钱又不耗费太多时间精力的兼职。今天&#xff0c;我想分享一个新的赚钱平台——Fiverr&#xff0c;让…

qt使用QAxObject操作excel程序关闭之后excel进程未被关闭的解决方案

&#x1f482; 个人主页:pp不会算法^ v ^ &#x1f91f; 版权: 本文由【pp不会算法v】原创、在CSDN首发、需要转载请联系博主 &#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 今天突然发现电脑变得很卡,我以为内存占用率过高了一看才50%&…

软件测试 需求

文章目录 1. 需求1.1 什么是需求1.2 为什么要有需求1.3 测试人员眼中的需求1.4 如何深入理解需求 2. 测试用例的概念2.1 什么是测试用例2.2 为什么要有测试用例 3. 软件错误&#xff08;BUG&#xff09;的概念4. 开发模型和测试模型4.1 软件的生命周期4.2 瀑布模型&#xff08;…

【深度学习笔记】6_10 双向循环神经网络bi-rnn

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 6.10 双向循环神经网络 之前介绍的循环神经网络模型都是假设当前时间步是由前面的较早时间步的序列决定的&#xff0c;因此它们都将信…

STM32---IIC通信协议(含源码,小白进)

写在前面&#xff1a;在前面的学习过程中&#xff0c;我们学习了串口通信的USART&#xff08;通用同步异步收发器&#xff09;&#xff0c;本节我们将继续学习一种串行通信协议——IIC通信协议。之前我使用51单片机也分享过相关的IIC通信的知识&#xff0c;其实本质的知识是相通…

Spring Boot 整合 MongoDB:构建高效的数据驱动应用

Spring Boot 整合 MongoDB&#xff1a;构建高效的数据驱动应用 在现代软件开发中&#xff0c;数据持久化是应用程序不可或缺的一部分。MongoDB&#xff0c;作为一个流行的NoSQL数据库&#xff0c;以其灵活的数据模型和强大的扩展性赢得了众多开发者的青睐。Spring Boot&#x…

LeetCode_Hot100_栈_394字符串解码_Python

1.题目&#xff08;中等难度&#xff09; 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b…

去哪里找视频素材?这几个视频素材资源网您看看

朋友们&#xff0c;是不是在抖音短视频的创作过程中感觉自己的视频素材库就像饭后的草莓派&#xff0c;美好但不够充实&#xff1f;别担心&#xff0c;我这就给你们送上几个超级赞的素材网站&#xff0c;保证让你的创作素材库瞬间丰富起来 1&#xff0c;蛙学府 这个网站简直就…

激光SLAM-重定位方案预研

-----------------------------------------------------待更新--------------------------------------

Delphi 的Read 与Readln 的区别

结合运行窗口&#xff0c;你输入1 2 3 4 这是一行ReadLn在读入时把这四个数当成一行&#xff0c;read(a,b)只读入了前两个数&#xff1a;1 2&#xff0c;就准备读下一行了&#xff0c;下一行输入3&#xff0c;再下一行输入2&#xff0c;所以输出1232&#xff1b; Read是逐个读…

Python列表及其操作详解,从此不再迷茫!

在前面的文章中&#xff0c;我们详细讲了六大数据类型中的数字类型&#xff0c;字符串类型。相信大家都能够熟练的掌握了。那么今天我们来讲解列表&#xff08;list&#xff09;。 这是一种常用且重要的数据类型&#xff0c;List可以用来存储一系列的元素&#xff0c;对于后期…

怎么看待Groq

用眼睛看。 就是字面上的意思用眼睛看。 我属于第一波玩到的,先给大家一个直观的印象,Groq到底有多快。 目前Groq只能选Llama的70b,和Mixtral的MoE,那我选7*8的这个MoE模型来实验。 这么好些字大概花了不到1秒,流式响应,其实是不是流式已经没那么重要了 ,然后看每秒Toke…

MongoDB官网查看 MongoClient 驱动API 文档的详细步骤

目录 MongoDB官网查看 MongoClient 驱动API 文档的详细步骤1、先进入[mongodb的官网](https://www.mongodb.com/zh-cn)&#xff0c;点击【服务器文档】2、点击这个 [MongoDB Documentation](https://www.mongodb.com/docs/) 文档。3、然后点开【Java】的驱动文档4、先查看同步的…