C++之类模板全特化和偏特化
类模板
类模板是通用类的描述,使用任意类型(泛型)来描述类的定义。
使用类模板的时候,指定具体的数据类型,让编译器生成该类型的类定义。
注意:函数模板中可以不指定具体数据类型,让编译器自动推到,但是类模板不可以。
注意:模板编程不支持分离式编译,即模板类/模板函数的声明与定义应该放在头文件里,否则会在链接时报错;
template <class T>
class 类模板名
{类的定义;
};注意
1)在创建对象的时候,必须指明具体的数据类型。
2)使用类模板时,数据类型必须适应类模板中的代码。
3)类模板可以为通用数据类型指定缺省的数据类型(C++11标准的函数模板也可以)。
4)模板类的成员函数可以在类外实现。
5)可以用new创建模板类对象。
6)在程序中,模板类的成员函数使用了才会创建。
下面给出示例
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template <class T1, class T2 = string>
class AA
{
public:T1 m_a; // 通用类型用于成员变量。T2 m_b; // 通用类型用于成员变量。AA() {} // 默认构造函数// 通用类型用于成员函数的参数。AA(T1 a, T2 b) :m_a(a), m_b(b) { }// 通用类型用于成员函数的返回值。T1 geta() // 获取成员m_a的值。{T1 a = 2; // 通用类型用于成员函数的代码中。return m_a + a;}T2 getb(); // 获取成员m_b的值。
};template <class T1, class T2>
T2 AA<T1, T2>::getb() // 获取成员m_b的值。
{return m_b;
}
int main()
{AA<int, string>* a = new AA<int, string>(3, "西施"); // 用模板类AA创建对象a。cout << "a->geta()=" << a->geta() << endl;cout << "a->getb()=" << a->getb() << endl;delete a;return 0;
}类模板全特化和部分特化
模板类具体化(特化、特例化)有两种:完全具体化和部分具体化。
具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。
具体化的模板类,成员函数类外实现的代码应该放在源文件中。
下面给出示例
#include <iostream>
using namespace std; // 类模板
template<class T1, class T2>
class AA {
public:T1 m_x;T2 m_y;AA(const T1 x, const T2 y) :m_x(x), m_y(y) { cout << "类模板:构造函数。\n"; }void show() const;
};
template<class T1, class T2>
void AA<T1, T2>::show() const
{cout << "类模板:x = " << m_x << ", y = " << m_y << endl;
}
// 类模板特化
template<>
class AA<int, string> {
public:int m_x;string m_y;AA(const int x, const string y) :m_x(x), m_y(y) { cout << "完全具体化:构造函数。\n"; }void show() const;
};void AA<int, string>::show() const
{cout << "完全具体化:x = " << m_x << ", y = " << m_y << endl;
}
// 类模板部分特化
template<class T1>
class AA<T1, string> {
public:T1 m_x;string m_y;AA(const T1 x, const string y) :m_x(x), m_y(y) { cout << "部分具体化:构造函数。\n"; }void show() const;
};
template<class T1>
void AA<T1, string>::show() const
{cout << "部分具体化:x = " << m_x << ", y = " << m_y << endl;
}
int main()
{// 具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。AA<int, string> aa1(8, "张三"); // 将使用完全具体化的类。AA<char, string> aa2(8, "李四"); // 将使用部分具体化的类。AA<int, double> aa3(8, 9666); // 将使用模板类。
}模板类于继承
1)模板类继承普通类(常见)。
2)普通类继承模板类的实例化版本。
3)普通类继承模板类。(常见)
4)模板类继承模板类。
5)模板类继承模板参数给出的基类(不能是模板类)。
下面主要讲普通类继承模板类
#include <iostream>
using namespace std; template<class T1, class T2>
class BB
{
public:T1 m_x;T2 m_y;BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了BB的构造函数。\n"; }void func2() const { cout << "调用了func2()函数:x = " << m_x << ", y = " << m_y << endl; }
};template<class T1, class T2>
class AA:public BB<T1,T2> // 普通类AA变成了模板类,才能继承模板类。
{
public:int m_a;AA(int a, const T1 x, const T2 y) : BB<T1,T2>(x,y),m_a(a) { cout << "调用了AA的构造函数。\n"; }void func1() { cout << "调用了func1()函数:m_a=" << m_a << endl;; }
};int main()
{AA<int,string> aa(3,8, "我是一只傻傻鸟。");aa.func1();aa.func2();return 0;
}模板类继承模板类
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。template<class T1, class T2>
class BB // 模板类BB。
{
public:T1 m_x;T2 m_y;BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了BB的构造函数。\n"; }void func2() const { cout << "调用了func2()函数:x = " << m_x << ", y = " << m_y << endl; }
};template<class T1, class T2>
class AA:public BB<T1,T2> // 普通类AA变成了模板类,才能继承模板类。
{
public:int m_a;AA(int a, const T1 x, const T2 y) : BB<T1,T2>(x,y),m_a(a) { cout << "调用了AA的构造函数。\n"; }void func1() { cout << "调用了func1()函数:m_a=" << m_a << endl;; }
};template<class T, class T1, class T2>
class CC :public BB<T1, T2> // 模板类继承模板类。
{
public:T m_a;CC(const T a, const T1 x, const T2 y) : BB<T1, T2>(x, y), m_a(a) { cout << "调用了CC的构造函数。\n"; }void func3() { cout << "调用了func3()函数:m_a=" << m_a << endl;; }
};int main()
{CC<int,int,string> cc(3,8, "芜湖");cc.func3();cc.func2();
}模板类继承模板参数给出的基类
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。class AA {
public:AA() { cout << "调用了AA的构造函数AA()。\n"; }AA(int a) { cout << "调用了AA的构造函数AA(int a)。\n"; }
};class BB {
public:BB() { cout << "调用了BB的构造函数BB()。\n"; }BB(int a) { cout << "调用了BB的构造函数BB(int a)。\n"; }
};class CC {
public:CC() { cout << "调用了CC的构造函数CC()。\n"; }CC(int a) { cout << "调用了CC的构造函数CC(int a)。\n"; }
};template<class T>
class DD {
public:DD() { cout << "调用了DD的构造函数DD()。\n"; }DD(int a) { cout << "调用了DD的构造函数DD(int a)。\n"; }
};template<class T>
class EE : public T { // 模板类继承模板参数给出的基类。
public:EE() :T() { cout << "调用了EE的构造函数EE()。\n"; }EE(int a) :T(a) { cout << "调用了EE的构造函数EE(int a)。\n"; }
};int main()
{EE<AA> ea1; // AA作为基类。EE<BB> eb1; // BB作为基类。EE<CC> ec1; // CC作为基类。EE<DD<int>> ed1; // DD<int>作为基类。// EE<DD> ed1; // DD作为基类,错误。
}
相关文章:
C++之类模板全特化和偏特化
类模板类模板是通用类的描述,使用任意类型(泛型)来描述类的定义。使用类模板的时候,指定具体的数据类型,让编译器生成该类型的类定义。注意:函数模板中可以不指定具体数据类型,让编译器自动推到…...
Python 手写数字识别 MNIST数据集下载失败
目录 一、MNIST数据集下载失败 1 失败的解决办法(经验教训): 2 亲测有效的解决方法: 一、MNIST数据集下载失败 场景复现:想要pytorchMINIST数据集来实现手写数字识别,首先就是进行MNIST数据集的下载&am…...
华为机试题:HJ61 放苹果(python)
文章目录博主精品专栏导航知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方法2、print() :打印输出。3、整型int() :将指定进制…...
【论文速递】ICCV2021 - 基于超相关压缩实现实时高精度的小样本语义分割
【论文速递】ICCV2021 - 基于超相关压缩的小样本语义分割 【论文原文】:Hypercorrelation Squeeze for Few-Shot Segmentation 【作者信息】:Juhong Min Dahyun Kang Minsu Cho 获取地址:https://openaccess.thecvf.com/content/ICCV2021/…...
单例模式(Singleton Pattern)
目录 1.什么是单例模式: 2.单例模式存在的原因: 3.单例模式的优缺点: 4.创建方式: 1. 单线程单例模式立即创建(饿汉式): 2. 单线程单例模式延迟创建(懒汉式)…...
docker file和compose
文章目录1.dockerfile(单机脚本)1.概念2.原理3.dockerfile核心四步4.命令2.docker compose1.概念2.注意事项3.常用字段4.常用命令1.dockerfile(单机脚本) 1.概念 通过脚本,生成一个镜像,并运行对应的容器…...
如何解决thinkphp验证码不能显示问题?
thinkPHP做验证码这一块,可以使用自带的验证码扩展,具体步骤如下: 一、安装扩展 composer require topthink/think-captcha 二、模版中使用 将原来静态页面的验证码图片替换为{:captcha_img()},这个会自动生成验证码图片。 <div>{:captcha_img()}</div> 或者 &…...
Vue极简使用
Vue安装Vue模板语法安装Vue 安装nodejs 这里我安装的是14.5.4版本 https://nodejs.org/download/release/v14.15.4/解压后配置一下环境变量就行 安装cnpm镜像 (这个安装的版本可能过高,后面安装Vue可能出问题) npm install -g cnpm --registryhttps://registry…...
【Nacos】Nacos配置中心服务端源码分析
上文说了Nacos配置中心客户端的源码流程,这篇介绍下Nacos配置中心服务端的源码。 服务端的启动 先来看服务启动时干了啥? init()方法上面有PostConstruct,该方法会在ExternalDumpService实例化后执行。 com.alibaba.nacos.config.server.s…...
第十五章 栅格数据重分类、栅格计算器、插值分析
文章目录第十五章 栅格数据分析第一章 栅格数据重分类第一节 栅格数据重分类第二节 栅格重分类的使用第三节 重分类的使用中的空值使用第四节 重分类的案例:分类统计面积第五节 坡度矢量分级图生成第二章 栅格计算器第一节 栅格计算器介绍第二节 栅格计算器使用第三…...
CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图
CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图 CS5260是一款高度集成的TYPEC转VGA转换方案芯片。 CS5260输出端接口:外接高清VGA设备如:显示器投影机电视带高清的设备,广泛应用于 笔记本Macbook Air 12寸USB3.1输出端对外接高清VGA设备如:显示器投影机电视…...
winform开发心得
最近一直在从事winform的开发,每次都是需要从网上查找资料才能对应具体风格要求,现在总结一下。 ui方面可以使用CSkin对应的一套ui,使用步骤 1.在窗口界面,工具箱空白处点击右键,弹出菜单有个”选择项“,点…...
学习周报-2023-0210
文章目录一 在SUSE11sp3系统中将openssh从6升级到8一 需求二 系统环境三 部署流程1.上传编译安装的软件包2.安装 gcc编译软件3.安装依赖zlib4.安装依赖openssl5.安装openssh二 在CentOS-6.9配置apache服务(3)---虚拟主机配置一 定义二 系统环境三 基于域…...
百度富文本UE的问题集合
百度富文本编辑能上传视频成功但是在浏览器不能播放、显示的问题百度富文本视频封面空白问题百度富文本编辑器UMEditor 添加视频无法删除百度富文本编辑器结果存数据库取出来到js赋值报错怎么让浏览器重新加载修改过的JS文件,而不是沿用缓存里的百度富文本编辑能上传…...
在Linux上安装node-v14.17.3和npm-6.14.13
记录:374场景:在CentOS 7.9操作系统上,安装node-v14.17.3-linux-x64环境。包括node-v14.17.3和npm-6.14.13。node命令应用和npm命令应用。版本:JDK 1.8 node v14.17.3 npm 6.14.13官网地址:https://nodejs.org/下载地址…...
机器学习框架sklearn之特征降维
目录特征降维概念特征选择过滤式①低方差特征过滤②相关系数③主成分分析特征降维 0维 标量 1维 向量 2维 矩阵 概念 降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程 注:正是…...
java实现二叉树(一文带你详细了解二叉树的)
🎇🎇🎇作者: 小鱼不会骑车 🎆🎆🎆专栏: 《数据结构》 🎓🎓🎓个人简介: 一名专科大一在读的小比特,努力学习编程是我唯一…...
学弟学妹少走弯路,超完整算法刷题路线出炉
大家好,我是帅地。 本篇文章主要讲解下面三个事: 1、自己学习算法的一些经历 2、大家学习算法存在的一些普遍问题 3、给大家规划的算法刷题路线 一、算法学习往事 记得当初学了 C 语言就开始刷题了,刷题倒不是面试,而是为了…...
Windows截取gif动态图的软件 ScreenToGif 的安装、使用教程
一、概述 👉GIF(Graphics Interchange Format),又称图形交换格式,是一种公用的图像文件格式标准,于1987年由Compu Serve公司成功研发并推出。 👉GIF用于以超文本标志语言方式显示索引彩色图像&a…...
C++程序设计——多态:虚函数、抽象类、虚函数表
注:以下示例均是在VS2019环境下 一、多态的概念 通俗来讲,多态就是多种形态,当不同的对象去完成某个行为时,会产生出不同的状态。即不同继承关系的类对象,去调用同一函数时,产生不同的行为。 比如”叫“这…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
李沐--动手学深度学习--GRU
1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...
java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟
众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了,延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp ,边缘服务器拉流推送到云服务器 …...
