【C++】第十四节—模版进阶(非类型模版参数+模板的特化+模版分离编译+模版总结)

【C++】第十四节—模版进阶(非类型模版参数+模板的特化+模版分离编译+模版总结)

你好,我是云边有个稻草人 

C++—本文章所属专栏,欢迎订阅,持续更新中!

目录

一、非类型模板参数

【非类型模版参数的用处在哪里? 】

【了解array 容器—array和普通数组的区别在哪里?—对越界的检查】

二、模板的特化(特殊化处理)

2.1 概念

2.2 函数模版特化

【函数模版特化可使用,但不推荐】 

2.3 类模版特化

【全特化】

【偏特化】

 【判断走哪个类模版?】

【类模版特化应用实例】

三、模版分离编译

3.1 什么是分离编译

3.2 模板的分离编译

 【分析】

3.3 解决办法

【分离定义扩展阅读】

四、模板总结

【优点】

【缺陷】


正文开始——

一、非类型模板参数

模板参数分为类型形参非类型形参

类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。

非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

注意:浮点数、类对象以及字符串是不允许作为非类型模板参数的。非类型的模板参数必须在编译期就能确认结果。类型模版参数和非类型模版参数都可以用缺省值,但是非类型模版参数是有限制的,只能用整型类型,浮点型,类类型等都是不可以的!
【非类型模版参数的用处在哪里? 】
#include<iostream> using namespace std; //#define N 10//宏定义 //只支持整型 template<class T,size_t N = 10>//非类型模版参数可以给缺省值 class Stack { private: T _a[N]; int _top; }; ////C++20以后才支持浮点数 //template<class T, double N = 10.1>//非类型模版参数可以给缺省值 //class Array //{ //private: //}; int main() { Stack<int,20> st1; Stack<int,200> st2; Stack<int> st3; return 0; }
【了解array 容器—array和普通数组的区别在哪里?—对越界的检查】

二、模板的特化(特殊化处理)

2.1 概念

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理。

比如:实现了一个专门用来进行小于比较的函数模板

class Date { public: Date(int year = 2025, int month = 7, int day = 9) :_year(year) , _month(month) , _day(day) { } bool operator<(const Date& d)const { return (_year < d._year) || (_year == d._year && _month < d._month) || ((_year == d._year && _month == d._month && _day == d._day)); } private: int _year; int _month; int _day; }; //函数模版 template<class T> bool Less(T left,T right) { return left < right; } int main() { Date d1(2025, 7, 9); Date d2(2025, 9, 9); Date* p1 = new Date(2025, 8, 9); Date* p2 = new Date(2025, 10, 9); cout << Less(1, 2) << endl;//可以判断,结果正确 cout << Less(d1, d2) << endl;//可以判断,结果正确 cout << Less(p1, p2) << endl;//结果随机。其实这里是对new出来的地址进行比较,当然是随机,那怎么办?—特化! return 0; }

可以看到,Less绝对多数情况下都可以正常比较,但是在特殊场景下就得到错误的结果。上述示例中,p1指向的d1显然小于p2指向的d2对象,但是Less内部并没有比较p1和p2指向的对象内容,而比较的是p1和p2指针的地址,这就无法达到预期而错误。 此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化类模板特化

2.2 函数模版特化

函数模板的特化步骤:

    Read more

    Flutter 三方库 web_ffi 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、全场景的 Web 浏览器 FFI(外部函数接口)与 WebAssembly 跨平台调用引擎

    欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 web_ffi 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、全场景的 Web 浏览器 FFI(外部函数接口)与 WebAssembly 跨平台调用引擎 在鸿蒙(OpenHarmony)系统的 Web 浏览器环境(Webview/Ohos Browser)开发高性能 Web 应用时,如何调用现有的 C/C++ 算法库(Wasm 格式)且能保持与原生 HAP 环境下的 dart:ffi 接口完全一致?web_ffi 为开发者提供了一套工业级的、基于 JS 绑定的

    By Ne0inhk
    哈希的介绍

    哈希的介绍

    1. unordered系列关联式容器     下面来看哈希,首先看关联式容器unorder_map和unorder_set,它们底层是哈希表,用法和map set一样。下面浅浅过一下,它是单向迭代器,因为没有rbegin和rend。也就是红黑树和哈希表实现的map和set用法几乎相同,区别是:1.unorder系列是单向迭代器。2.unorder系列遍历出来不是有序的。下面演示一下: 它只能去重,不能排序,它也是有multi版本的。再演示一下unorder_map: 2.哈希     下面正式看哈希,什么是哈希呢?我们以前遇到的搜索有这样几类:首先是暴力查找,在一个数组里都查,这样非常慢。于是有人衍生出了有序数组的二分查找,但它的前提是排序,而且增删查改不方便,过程中为了保证有序会涉及大量的数据挪动。因此衍生出了平衡搜索树,此时基础上又出现了新的搜索,这种搜索叫哈希(散列)。它的本质是存储的值跟存储位置建立出一个映射关系,什么意思呢,先来看一个计数排序的样例: 有上面这样的一组值,最小的值是15,最大的值是30,总共开了16个空间。然后存映射关系(次数),15映射第一个位

    By Ne0inhk
    【优选算法 | 双指针】双指针大揭秘:如何用两根指针优化你的代码

    【优选算法 | 双指针】双指针大揭秘:如何用两根指针优化你的代码

    算法相关知识点可以通过点击以下链接进行学习一起加油! 在本篇文章中,我们将深入探索双指针算法的奥秘。从基础概念到实际应用,带你全面了解如何利用两根指针高效解决各种编程问题。无论你是刚接触算法的新人,还是希望提升代码性能的老手,双指针都是你不可忽视的利器! 🌈个人主页:是店小二呀 🌈C/C++专栏:C语言\ C++ 🌈初/高阶数据结构专栏: 初阶数据结构\ 高阶数据结构 🌈Linux专栏: Linux 🌈算法专栏:算法 🌈Mysql专栏:Mysql 🌈你可知:无人扶我青云志 我自踏雪至山巅 文章目录 * 283.移动零[数组划分] * 1089.复写零[遍历角度] * 202.快乐数[快慢指针] * 11.盛水最多容器[对撞指针、单调性] * 611.有效三角形的个数[对撞指针、单调性] * 179.和为s的两个数字[对撞指针、单调性]

    By Ne0inhk
    [力扣每日习题][1339]. 分裂二叉树的最大乘积 2026.01.07

    [力扣每日习题][1339]. 分裂二叉树的最大乘积 2026.01.07

    难度评级:中等 题目: 给你一棵二叉树,它的根为 root 。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。 由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回。 示例1: 输入:root = [1,2,3,4,5,6] 输出:110 解释:删除红色的边,得到 2 棵子树,和分别为 11 和 10 。它们的乘积是 110 (11*10) 示例2: 输入:root = [1,null,2,3,4,null,

    By Ne0inhk