【C++】模板学习(二)

news2024/11/23 4:00:51

模板学习

  • 非类型模板参数
  • 模板特化
    • 函数模板特化
    • 类模板特化
      • 全特化
      • 偏特化
  • 模板分离编译
  • 模板总结

非类型模板参数

模板参数除了类型形参,还可以是非类型的形参。
非类型形参要求用一个常量作为类(函数)模板的一个参数。这个参数必须是整形家族的。浮点数,字符串等都是不允许用作非类型模板参数的。
非类型模板参数在编译期间就已经确定结果了。

// N 就是定义的非类型模板参数
template <class T, size_t N = 10>
class array
{
private:
	T _array[N];
};

模板特化

模板可以帮助泛型编程,但当处理到一些特殊类型的时候可能也会出错。

template<class T>
bool Less(T num1, T num2)
{
	return num1 < num2;
}
void Test1()
{
	cout << Less(1, 2) << endl;

	int a = 1;
	int b = 2;
	int* pa = &a;
	int* pb = &b;
	cout << Less(pa, pb) << endl;
}

从上面代码可以看到,pa指向的a是小于pb指向的b的,Less并没有比较papb所指向的对象的内容,而只能比较papb指针的地址,导致出现错误结果。
此时可以通过对模板的特化来处理问题:在原模板的基础上,针对特殊类型采用特殊化的的实现方式。
模板特化可以分为函数模板特化和类模板特化,先来看函数模板特化。

函数模板特化

模板的特化必须先有一个基础的模板。
函数模板特化方式:
关键字template后面接一对空的尖括号<>
函数名后跟一对尖括号<>,尖括号中指定需要特化的类型;
函数形参表中参数的类型要和指定特化的类型呼应。

template<class T>
bool Less(T num1, T num2)
{
	return num1 < num2;
}

template<>
bool Less<int*>(int* num1, int* num2)
{
	return *num1 < *num2;
}

void Test2()
{
	cout << Less(1, 2) << endl;

	int a = 1;
	int b = 2;
	int* pa = &a;
	int* pb = &b;
	cout << Less(pa, pb) << endl;
}

一般情况下对于函数模板处理有困难的类型,也可以直接给出,这样实现简单明了,代码可读性也更高。

bool Less(int* num1, int* num2)
{
	return *num1 < num2;
}

类模板特化

全特化

顾名思义,就是将模板参数列表中所有的类型参数都确定化。

template<class T1, class T2>
class A
{
public:
	A()
	{
		cout << "A<T1, T2>" << endl;
	}
};

template<>
class A<int, double>
{
public:
	A()
	{
		cout << "A<int, double>" << endl;
	}
};

void Test3()
{
	A<int, int> a1;
	A<int, double> a2;
}

在这里插入图片描述

偏特化

偏特化有两种表现方式:

  1. 部分特化
    将模板参数列表中的部分类型参数进行特化。
template<class T1, class T2>
class A
{
public:
	A()
	{
		cout << "A<T1, T2>" << endl;
	}
};

template<class T1>
class A<T1, int>
{
public:
	A()
	{
		cout << "A<T1, int>" << endl;
	}
};

void Test4()
{
	A<int, int> a1;
	A<int, double> a2;
}

在这里插入图片描述

  1. 对参数更进一步的特化
template<class T1, class T2>
class A
{
public:
	A()
	{
		cout << "A<T1, T2>" << endl;
	}
};

template<class T1, class T2>
class A<T1*, T2*>
{
public:
	A()
	{
		cout << "A<T1*, T2*>" << endl;
	}
};

template<class T1, class T2>
class A<T1&, T2&>
{
public:
	A()
	{
		cout << "A<T1&, T2&>" << endl;
	}
};

void Test5()
{
	A<int, double> a1;
	A<int*, double*> a2;
	A<int&, double&> a3;
}

在这里插入图片描述

模板分离编译

将一个程序中所有源文件单独编译成目标文件,最后所有目标文件链接形成一个可执行文件的过程就称为分离编译模式。
对于模板分离编译的问题可以参考刘未鹏大佬在CSDN上的这篇博客 为什么C++编译器不能支持对模板的分离式编译。
知道了模板分离编译时,链接会出错的原因是,分开编译的模板定义不能够实例化,符号导出表中没有其对应的符号地址以供链接。
所以解决模板分离编译可以将声明和定义都放到一个xxx.hppxxx.h文件中。

模板总结

模板体现了复用和泛型编程,标准模板库(STL)的实现离不开模板。
同时,模板也可能导致代码膨胀问题,导致编译时间变长。模板的报错也会导致错误信息凌乱,不易定位错误。

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

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

相关文章

协同办公企业网盘:实用性探究与切实可行的共享方式

在数字时代&#xff0c;如何解决信息存储是企业管理中的一个课题。怎样在安全存储文件的信息的同时又能够满足企业协同办公的需求呢&#xff1f; 企业网盘的出现&#xff0c;为企业提供安全存储服务的同时&#xff0c;也满足了协同办公的需求&#xff0c;因此受到了广泛关注。 …

Gartner最新报告,分析超大规模边缘解决方案

当下&#xff0c;酝酿能量的超级边缘。 最近&#xff0c;我们在谈视频化狂飙、谈AIGC颠覆、谈算力动能不足&#xff0c;很少谈及边缘。但“边缘”恰恰与这一切相关&#xff0c;且越发密不可分&#xff0c;它是未来技术发展的极大影响因子。 “到2025年&#xff0c;超过70%的组…

opencv的Mask操作,选择图片中感兴趣的区域

最近做目标检测任务的时候&#xff0c;需要对固定区域的内容进行检测&#xff0c;要用到opencv的mask操作&#xff0c;选择图片固定的区域 代码 import cv2 import numpy as npimg cv2.imread(data/images/smoking.png)# 弹出一个框 让你选择ROI | x,y是左上角的坐标 x,y,w,…

【论文精读3】基于历史抽取信息的摘要抽取方法

前言 论文分享 今天分享的是来自2018ACL的长文本抽取式摘要方法论文&#xff0c;作者来自哈尔滨工业大学和微软&#xff0c;引用数369 Neural Document Summarization by Jointly Learning to Score and Select Sentences 摘要抽取通常分为两个部分&#xff0c;句子打分和句子…

vue3单选选择全部传all,否则可以多选

<el-form-item label"发布范围-单位选择"><el-radio-group v-model"formData.unitRadio" change"getUnit"><el-radio label"ALL" click.prevent"radioChange(ALL)">全部</el-radio><el-radio la…

原子操作的重要性

原子操作&#xff1a;要么不做&#xff0c;要么一次性做完 非原子操作 其实ABCD都是对的。 B选项&#xff1a;正常执行&#xff0c;I线程执行2条语句全部执行完毕,再执行II线程重新执行一遍foo函数。 C选项&#xff1a;先执行I线程foo函数第一行代码&#xff0c;然后跳转执行…

【JS】类 class

【JS】类 class 定义类类的方法类继承静态方法 类&#xff08;class&#xff09;是用于创建对象的模板。 我们使用 class 关键字来创建一个类&#xff0c;类体在一对大括号 {} 中&#xff0c;我们可以在大括号 {} 中定义类成员的位置&#xff0c;如方法或构造函数。 每个类中…

Java-很深我只知其一-泛型

Java-很深我只知其一-泛型 目录 泛型历史 泛型类/泛型接口 泛型方法 泛型属性 泛型约束 泛型历史 JAVA 泛型&#xff08;generics&#xff09;是 JDK 5 中引入的一个新特性, 允许程序员在编程时指定类型参数&#xff0c;使编译器可以在编译代码时检测到非法的类型。泛型的…

商城免费搭建之java商城 开源java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c bbc

&#xfeff; 1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、R…

面试之HashMap

1.什么是集合框架Java的集合主要有两个根接口Collection和Map派生出来的,Collection派生出来了三个子接口:List,Queue,Set。因此Java集合大致可分为List,Queue,Set,Map四种体系结构。2.HashMap与TreeMapHashMap是直接实现Map接口,而TreeMap是实现SortedMap接口的,所以两个还…

RISC-V - 小记

文章目录 关于 RISC-V安装 关于 RISC-V RISC : Reduced Instruction Set Computing RISC-V(“RISC five”)的目标是成为一个通用的指令集架构(ISA) 官网&#xff1a;https://riscv.orggithub : https://github.com/riscv 教程 [完结] 循序渐进&#xff0c;学习开发一个RISC-…

如何与 Dillard‘s 建立 EDI 连接?

Dillards 是主营时装、化妆品和家居用品的零售商&#xff0c;为顾客提供高质量的商品和优质的购物体验。2022年&#xff0c;Dillards 公司位列当年《财富》美国 500 强排行榜第 488 名。本文将为大家介绍 Dillards 的 EDI 需求&#xff0c;了解如何快速对接 Dillards EDI。 Dil…

Stable Diffusion - Stable Diffusion WebUI 支持 SDXL 1.0 模型的环境配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132056980 SDXL v1.0 版本 是 Stable Diffusion 的最新版本&#xff0c;是基于潜在扩散模型的文本到图像生成技术&#xff0c;能够根据输入的任何…

瀑布流布局columns

瀑布流布局其核心是基于一个网格的布局&#xff0c;而且每行包含的项目列表高度是随机的&#xff08;随着自己内容动态变化高度&#xff09;&#xff0c;同时每个项目列表呈堆栈形式排列&#xff0c;最为关键的是&#xff0c;堆栈之间彼此之间没有多余的间距差存大。还是上张图…

sass的模块化,@import的编译时和运行时详解

sass如同css一样 可以模块化。 css中通过import来实现模块化&#xff0c; 但是两者有些不同&#xff0c;css是会参与到运行时的&#xff0c;也就是说运行的过程中有多个css文件&#xff0c;通过import指令导入进来。但是sass并不是个运行时态&#xff0c;sass是一个编译时态。…

六、JVM-垃圾收集器浅析

垃圾收集器浅析 主 JVM参数 3.1.1 标准参数 -version -help -server -cp3.1.2 -X参数 非标准参数&#xff0c;也就是在JDK各个版本中可能会变动 -Xint 解释执行 -Xcomp 第一次使用就编译成本地代码 -Xmixed 混合模式&#xff0c;JVM自己来决定3.1.3 -XX参数 使用得…

图片怎么压缩大小?值得一看的图片压缩方法

图片是我们生活和工作中必不可少的文件&#xff0c;为了能够有效保存、发送&#xff0c;我们需要适当压缩其大小&#xff0c;但很多朋友不知道怎么压缩图片&#xff0c;或者压缩后造成了图片清晰度受损&#xff0c;怎么才能既压缩图片的大小&#xff0c;又能避免清晰度受到影响…

为什么选择Docusaurus构建API文档?

在现代化软件开发中&#xff0c;文档对于软件成功的重要性不言而喻。然而&#xff0c;管理和维护文档站点往往会给开发者带来额外的负担。为了帮助开发人员快速构建易于管理和维护的文档站点&#xff0c;Docusaurus应运而生。本文将深入探讨为什么选择Docusaurus构建您的文档站…

Activiity跳转startActivity源码分析Activity启动流程(下)

调用ActivityThread子类ClientTranslationHandler的scheduleTranslation 注意上图有个sendMessage的 接着会执行translacationExecutor的execute方法。 都会走cycleToPath方法 cycleToPath方法对应的performLifecycleSequence 调用Actvitiy各个生命周期。 然后是第二种情况&am…

效率提升丨大学必看校园安全实用技巧

在当今社会&#xff0c;教育是培养人才、传承文明的重要场所。然而&#xff0c;教学楼作为学生、教师和员工活动的核心区域&#xff0c;也存在着潜在的安全隐患&#xff0c;其中最为突出的风险之一是火灾。火灾不仅危及生命财产&#xff0c;还可能给整个学校带来不可估量的损失…