C++模板(下)

【C++修炼秘籍】模板(下)

🌸心有所向,日复一日,必有精进

🌸专栏《C++修炼秘籍》

🌸作者:早凉


目录

【C++修炼秘籍】模板(下)

文章目录

前言

一、非类型的模板参数

二、模板的特化

三、模板分离编译

总结


前言

泛型编程的有力支撑——模板,在上次的文章中已经可以使用起来,也对STL的学习有了很大作用,本文会再次将一些细小知识汇总作为参考。


一、非类型的模板参数

类型模板,T是类型,在下方的场景中,如果我们想在类中开辟数组,如果通过宏,我们就必须修改宏; 

template<class T>//是类型模板
#define N 10
class Array
{
    private:
       T a;
       T a[N]; 
}
int main()

{
    Array<int> a1;
    Array<double>a2;
}

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

template<class T ,size_t N = 10>//后后边就是非类型怒版参数
{
    private:
        T _arry;
        T _a[N];
}
int main()

{
	array<int,10>a2;
    int a3[10];
}

 在库里,C++11中支持的一个静态数组,这里就是实现非类型的模板参数。

  ❓但是C语言就有静态数组支持啊?为什么库里还要在C++11里还要实现什么?

 诶,我们发现我们这不是越界访问了吗?问什么编译器没报错啊,这是很危险的啊,

 这时我们发现,array是强制检查的。

原生数组对于越界的检查:越界读不检查;越界写会抽查

array对于越界的检查::array只要越界就检查,比起原生数组更加严格;

 ❗️ 注意

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

2、非类型的模板参数必须在编译器就能确认结果;

二、模板的特化

函数模板

针对某些类型进行特殊处理例如:日期类

template<class T>
    bool Less(T left,T right)
{
    return left<right;
}
//是上面那个特殊处理针对Date的特化
template<>
bool Less<Date*>(Date*left,Date*right)
{
    return *left<*right;
}
//构成重载也是可以
bool Less(Date*left,Date*right)
{
    return *left<*right;
}
Date d1();
Date d1();
cout<<Less(d1,d2)<<endl;
Date* p1 = &d1;
Date* p2 = &d2;
cout<<Less(p1,p2)<<endl;

类模板

类模板就不能写个函数了,只能特化;

    template<class T,class N>
    class D{
        public:
            D(){
                cout<<"T,N"<<endl;
            }
        private:
        	T t;
        	N n;
    }
//特化全特化
    template<>
    class D<double,double>{
        public:
            D(){
                cout<<"double,double"<<endl;
               }
        private:
    }

半特化/偏特化  

    template<class T>
    class D<T,char>{
        public:
            D(){
                cout<<"T,char"<<endl;
               }
        private:
    }

参数类型进一步限制 (也属于半特化) 

template<class T,class N>
class D<T*,N*>
{
public:
	D(){cout<<"T*,N*"<<endl;}
}
template<class T,class N>
class D<T&,N&>
{
public:
	D(){cout<<"T&,N&"<<endl;}
}

 ❗️  体现匹配原则:有全特化就优先全特化,其次半特化,最后模板;

三、模板分离编译

声明和定义分离是有大问题的 :

//template.h
#pragma once
template<class T>
T Add(const T& left, const T& right);
///template.h///
#include"template.h"
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
///test.h//
#include<iostream>
using namespace std;
#include"template.h"
int main()
{
	Add(11, 22);
	Add(3.2, 2.1);
	return 0;
}

 

发现这里我们找不到Add函数呀,这是因为 在add.cpp中在没有传参的时候不会对Add模板实例化,因此不会产生具体的函数,在main.obj中调用Add<int>在编译器链接是才会找地址,但是这俩函数没有实例化成具体代码,因此链接报错。

  如何解决?

1、将声明和定义放到一个文件 ;
2、模板定义的位置显式实例化;;

template int Add<int>(const int&, const int&);
template double Add<double>(const double&, const double&);

上述是函数模板,那么类模板该怎么办呢?

 

/.h/
#pragma once
template <class T>
class CSwap{
public:
	CSwap(T a, T b);
	void Swap();
public:
	T _a;
	T _b;
};
/CSwap.cpp///
#include"template.h"
template <class T>
void CSwap<T>::Swap()
{
	T tmp = _a;
	_a = _b;
	_b = tmp;
}
template <class T>
CSwap<T>::CSwap(T a, T b)
{
	_a = a; _b = b;
}
///test.cpp/
#include<iostream>
using namespace std;
#include"template.h"
int main()
{

	CSwap<int> c(1,2);
	c.Swap();
	cout << c._a << " " << c._b << endl;
}

 

看着熟悉的报错!那么类模板怎么解决呢?——在CSwap.cpp文件中加入:

template
class CSwap<int>;


总结

模板的缺点

分离编译,链接之前不会交互,没有实例化;模板的报错特别**,就是会给人打电报的感觉,摸不到头脑;模板会导致代码膨胀问题,也会导致编译时间变长

优点:

模板复用了代码,节省资源,更快的迭代开发,产生了C++的标准模板库(STL)
增强了代码的灵活性


如果觉得有帮助的话,可以点赞 + 收藏 + 评论支持一下哦!这对我的帮助很大~:)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[C#][opencvsharp]opencvsharp sift和surf特征点匹配

SIFT特征和SURF特征比较 SIFT特征基本介绍 SIFT(Scale-Invariant Feature Transform)特征检测关键特征&#xff1a; 建立尺度空间&#xff0c;寻找极值关键点定位&#xff08;寻找关键点准确位置与删除弱边缘&#xff09;关键点方向指定关键点描述子 建立尺度空间&#xff0…

谈谈BlueFS

目录 前言数据结构标识一个文件文件系统的全局记录事务记录超级块 启动流程磁盘管理读写流程创建文件流程为文件写数据把数据下刷到磁盘读流程 参考资料 前言 BlueFS具体是个什么东西呢&#xff1f; 如上图&#xff0c;在Ceph里&#xff0c;使用BlueStore作为默认的存储引擎。…

python爬虫3

1.异常处理&#xff0c;使代码更加健壮 静态cookie可视绕过登录的限制 快代理是一个代理平台 # https://movie.douban.com/j/chart/top_list?type5&interval_id100%3A90&action& # start0&limit20# https://movie.douban.com/j/chart/top_list?type5&int…

Unity SRP 管线【第九讲:URP 点光源与聚光灯】

文章目录 CPU数据搜集GPU数据使用光照计算 CPU数据搜集 我们只能支持有限数量的其他灯。并将这些灯光数据&#xff08;位置、颜色、阴影强度、方向光光源、灯光遮蔽Probe、灯光层级Mask&#xff09;发送到GPU以供场景中所有物体渲染使用。 //ForwardLights.cs 额外光源数量与…

人工智能基础-Numpy的arg运算-Fancy Indexing-比较

索引 获取最小值最大值索引 np.argmin(x) np.argmax(x)排序和使用索引 np.sort(x)Fancy Indexing 索引 二维数组的应用 numpy.array 的比较 比较结果和Fancy Indexing

linux搭建jupyter

查看虚拟环境 conda info --envs进入虚拟环境 conda activate my_env pip install jupyter pip install ipykernel1. jupyter notebook启动 1.1 创建临时jupyter notebook任务 jupyter notebook --ip0.0.0.0 --no-browser --allow-root --notebook-dir/home/xxx1.2 jupyter…

vue-cli初始化项目很慢?

第一种情况 大部分是由于npm的镜像源不是淘宝的 cmd输入npm config get registry查看是不是淘宝的&#xff0c;是的话看第二种情况试试不是的话输入npm config set registry https://registry.npm.taobao.org 第二种情况 vue-cli配置文件不是使用淘宝镜像源的 找到文件.vue…

【Mysql】数据库架构学习合集

目录 1. Mysql整体架构1-1. 连接层1-2. 服务层1-3. 存储引擎层1-4. 文件系统层 2. 一条sql语句的执行过程2-1. 数据库连接池的作用2-2. 查询sql的执行过程2-1. 写sql的执行过程 1. Mysql整体架构 客户端&#xff1a; 由各种语言编写的程序&#xff0c;负责与Mysql服务端进行网…

MySQL系列:系列结构和基础管理

文章目录 MySQL工作模型及实例MySQL 客户端/服务器工作模型&#xff08;C/S&#xff09;服务端&#xff1a;实例MySQLd的程序结构MySQL的逻辑结构MySQL的物理存储结构 MySQL基础管理用户管理权限管理连接管理初始化配置启动关闭多实例 MySQL工作模型及实例 MySQL 客户端/服务器…

Python之代码覆盖率框架coverage使用介绍

Python代码覆盖率工具coverage.py其实是一个第三方的包&#xff0c;同时支持Python2和Python3版本。 安装也非常简单&#xff0c;直接运行&#xff1a; pip install coverage 安装完成后&#xff0c;会在Python环境下的\Scripts下看到coverage.exe&#xff1b; 首先我们编写…

测试access和trunk口的区别(华为)

思科设备参考&#xff1a;测试access和trunk口的区别&#xff08;思科&#xff09; 一&#xff0c;实验目的 实现同一 Vlan 内的主机互通&#xff0c;不同 Vlan 间的主机隔离。 二&#xff0c;配置前测试 PC1分别ping PC2、PC3、PC4都能通&#xff0c;因为四台PC默认同处于v…

【CSS】css选择器和css获取第n个元素(:nth-of-type(n)、:nth-child(n)、first-child和last-child)

:nth-of-type、:nth-child的区别 一、css选择器二、:nth-of-type、:nth-child的区别:nth-of-type(n)&#xff1a;选择器匹配属于父元素的特定类型的第N个子元素:nth-child(n)&#xff1a;选择器匹配属于其父元素的第 N 个子元素&#xff0c;不论元素的类型:first-child&#xf…

【蓝桥杯冲冲冲】动态规划学习 [NOIP2003 提高组] 加分二叉树

【蓝桥杯冲冲冲】动态规划学习 [NOIP2003 提高组] 加分二叉树 蓝桥杯备赛 | 洛谷做题打卡day24 文章目录 蓝桥杯备赛 | 洛谷做题打卡day24[NOIP2003 提高组] 加分二叉树题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示数据规模与约定思路 题解代码我的一些话 [NOI…

如何使用内网穿透工具在公网实现实时监测DashDot服务器仪表盘

文章目录 1. 本地环境检查1.1 安装docker1.2 下载Dashdot镜像 2. 部署DashDot应用3. 本地访问DashDot服务4. 安装cpolar内网穿透5. 固定DashDot公网地址 本篇文章我们将使用Docker在本地部署DashDot服务器仪表盘&#xff0c;并且结合cpolar内网穿透工具可以实现公网实时监测服务…

idea docker 镜像生成太慢太大问题

文章目录 前言一、更小的jdk基础镜像二、服务瘦包&#xff08;thin jar&#xff09;2.1 maven2.2 修改dockerfile2.3 container run options 三、 基础jdk镜像入手&#xff1f;总结 前言 idea docker 内网应用实践遗留问题 idea docker插件 build 服务镜像太慢服务镜像太大 …

【蓝桥杯51单片机入门记录】LED

目录 一、基础 &#xff08;1&#xff09;新建工程 &#xff08;2&#xff09;编写前准备 二、LED &#xff08;1&#xff09;点亮LED灯 &#xff08;2&#xff09;LED闪烁 延时函数的生成&#xff08;stc-isp中生成&#xff09; 实现 &#xff08;3&#xff09;流水灯…

flutter GridView控件实践

gridView顶部自带padding问题 如图所示&#xff1a; 顶部有一个比较大的padding。 如何处理&#xff1a;给gridView设置&#xff1a;padding: EdgeInsets.zero,

C#,桌面游戏编程,数独游戏(Sudoku Game)的算法与源代码

本文包括以下内容&#xff1a; &#xff08;1&#xff09;数独游戏的核心算法&#xff1b; &#xff08;2&#xff09;数独游戏核心算法的源代码&#xff1b; &#xff08;3&#xff09;数独游戏的部分题目样本&#xff1b; &#xff08;4&#xff09;适老版《数独》的设计原则…

JAVA操作Rabbitmq-原理讲的很详细

这篇文章来源于稀土掘金&#xff0c;来源&#xff1a;https://juejin.cn/post/7132268340541653005&#xff0c;主要用来收藏学习。 常见的消息队列很多&#xff0c;主要包括 RabbitMQ、Kafka、RocketMQ 和 ActiveMQ&#xff0c;相关的选型可以看我之前的系列&#xff0c;这篇文…

用Python处理TDC激光测距数据并绘制为图片

用Python处理TDC激光测距数据并绘制为图片 说明一、定义全局变量变二、主函数入口三、处理原始文件数据四、将数据叠加统计生成图片五、额外的辅助函数六、将数据进行各种形式统计叠加七、原始数据形式八、 测试结果 说明 1. 主要是将TDC激光测距数据进行统计叠加并绘制为图片…