当前位置: 首页 > news >正文

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++之类模板全特化和偏特化

类模板类模板是通用类的描述&#xff0c;使用任意类型&#xff08;泛型&#xff09;来描述类的定义。使用类模板的时候&#xff0c;指定具体的数据类型&#xff0c;让编译器生成该类型的类定义。注意&#xff1a;函数模板中可以不指定具体数据类型&#xff0c;让编译器自动推到…...

Python 手写数字识别 MNIST数据集下载失败

目录 一、MNIST数据集下载失败 1 失败的解决办法&#xff08;经验教训&#xff09;&#xff1a; 2 亲测有效的解决方法&#xff1a; 一、MNIST数据集下载失败 场景复现&#xff1a;想要pytorchMINIST数据集来实现手写数字识别&#xff0c;首先就是进行MNIST数据集的下载&am…...

华为机试题:HJ61 放苹果(python)

文章目录博主精品专栏导航知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方法2、print() &#xff1a;打印输出。3、整型int() &#xff1a;将指定进制&#xf…...

【论文速递】ICCV2021 - 基于超相关压缩实现实时高精度的小样本语义分割

【论文速递】ICCV2021 - 基于超相关压缩的小样本语义分割 【论文原文】&#xff1a;Hypercorrelation Squeeze for Few-Shot Segmentation 【作者信息】&#xff1a;Juhong Min Dahyun Kang Minsu Cho 获取地址&#xff1a;https://openaccess.thecvf.com/content/ICCV2021/…...

单例模式(Singleton Pattern)

目录 1.什么是单例模式&#xff1a; 2.单例模式存在的原因&#xff1a; 3.单例模式的优缺点&#xff1a; 4.创建方式&#xff1a; 1. 单线程单例模式立即创建&#xff08;饿汉式&#xff09;&#xff1a; 2. 单线程单例模式延迟创建&#xff08;懒汉式&#xff09;&#xf…...

docker file和compose

文章目录1.dockerfile&#xff08;单机脚本&#xff09;1.概念2.原理3.dockerfile核心四步4.命令2.docker compose1.概念2.注意事项3.常用字段4.常用命令1.dockerfile&#xff08;单机脚本&#xff09; 1.概念 通过脚本&#xff0c;生成一个镜像&#xff0c;并运行对应的容器…...

如何解决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镜像 (这个安装的版本可能过高&#xff0c;后面安装Vue可能出问题) npm install -g cnpm --registryhttps://registry…...

【Nacos】Nacos配置中心服务端源码分析

上文说了Nacos配置中心客户端的源码流程&#xff0c;这篇介绍下Nacos配置中心服务端的源码。 服务端的启动 先来看服务启动时干了啥&#xff1f; init()方法上面有PostConstruct&#xff0c;该方法会在ExternalDumpService实例化后执行。 com.alibaba.nacos.config.server.s…...

第十五章 栅格数据重分类、栅格计算器、插值分析

文章目录第十五章 栅格数据分析第一章 栅格数据重分类第一节 栅格数据重分类第二节 栅格重分类的使用第三节 重分类的使用中的空值使用第四节 重分类的案例&#xff1a;分类统计面积第五节 坡度矢量分级图生成第二章 栅格计算器第一节 栅格计算器介绍第二节 栅格计算器使用第三…...

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图 CS5260是一款高度集成的TYPEC转VGA转换方案芯片。 CS5260输出端接口:外接高清VGA设备如:显示器投影机电视带高清的设备&#xff0c;广泛应用于 笔记本Macbook Air 12寸USB3.1输出端对外接高清VGA设备如:显示器投影机电视…...

winform开发心得

最近一直在从事winform的开发&#xff0c;每次都是需要从网上查找资料才能对应具体风格要求&#xff0c;现在总结一下。 ui方面可以使用CSkin对应的一套ui&#xff0c;使用步骤 1.在窗口界面&#xff0c;工具箱空白处点击右键&#xff0c;弹出菜单有个”选择项“&#xff0c;点…...

学习周报-2023-0210

文章目录一 在SUSE11sp3系统中将openssh从6升级到8一 需求二 系统环境三 部署流程1.上传编译安装的软件包2.安装 gcc编译软件3.安装依赖zlib4.安装依赖openssl5.安装openssh二 在CentOS-6.9配置apache服务&#xff08;3&#xff09;---虚拟主机配置一 定义二 系统环境三 基于域…...

百度富文本UE的问题集合

百度富文本编辑能上传视频成功但是在浏览器不能播放、显示的问题百度富文本视频封面空白问题百度富文本编辑器UMEditor 添加视频无法删除百度富文本编辑器结果存数据库取出来到js赋值报错怎么让浏览器重新加载修改过的JS文件&#xff0c;而不是沿用缓存里的百度富文本编辑能上传…...

在Linux上安装node-v14.17.3和npm-6.14.13

记录&#xff1a;374场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;安装node-v14.17.3-linux-x64环境。包括node-v14.17.3和npm-6.14.13。node命令应用和npm命令应用。版本&#xff1a;JDK 1.8 node v14.17.3 npm 6.14.13官网地址&#xff1a;https://nodejs.org/下载地址…...

机器学习框架sklearn之特征降维

目录特征降维概念特征选择过滤式①低方差特征过滤②相关系数③主成分分析特征降维 0维 标量 1维 向量 2维 矩阵 概念 降维是指在某些限定条件下&#xff0c;降低随机变量&#xff08;特征&#xff09;个数&#xff0c;得到一组“不相关”主变量的过程 注&#xff1a;正是…...

java实现二叉树(一文带你详细了解二叉树的)

&#x1f387;&#x1f387;&#x1f387;作者&#xff1a; 小鱼不会骑车 &#x1f386;&#x1f386;&#x1f386;专栏&#xff1a; 《数据结构》 &#x1f393;&#x1f393;&#x1f393;个人简介&#xff1a; 一名专科大一在读的小比特&#xff0c;努力学习编程是我唯一…...

学弟学妹少走弯路,超完整算法刷题路线出炉

大家好&#xff0c;我是帅地。 本篇文章主要讲解下面三个事&#xff1a; 1、自己学习算法的一些经历 2、大家学习算法存在的一些普遍问题 3、给大家规划的算法刷题路线 一、算法学习往事 记得当初学了 C 语言就开始刷题了&#xff0c;刷题倒不是面试&#xff0c;而是为了…...

Windows截取gif动态图的软件 ScreenToGif 的安装、使用教程

一、概述 &#x1f449;GIF&#xff08;Graphics Interchange Format&#xff09;&#xff0c;又称图形交换格式&#xff0c;是一种公用的图像文件格式标准&#xff0c;于1987年由Compu Serve公司成功研发并推出。 &#x1f449;GIF用于以超文本标志语言方式显示索引彩色图像&a…...

C++程序设计——多态:虚函数、抽象类、虚函数表

注&#xff1a;以下示例均是在VS2019环境下 一、多态的概念 通俗来讲&#xff0c;多态就是多种形态&#xff0c;当不同的对象去完成某个行为时&#xff0c;会产生出不同的状态。即不同继承关系的类对象&#xff0c;去调用同一函数时&#xff0c;产生不同的行为。 比如”叫“这…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解&#xff1a;从决策树开始理解三、解法一&#xff1a;二叉决策树 DFS四、解法二&#xff1a;组合式回溯写法&#xff08;推荐&#xff09;五、解法对比 递归算法是编程中一种非常强大且常见的思想&#xff0c;它能够优雅地解决很多复杂的…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!

今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等&#xff0c;设置经线、纬线都以10间隔显示。 2、需要插入背会归线&#xf…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

李沐--动手学深度学习--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流 然后客户端连服务器 中转多了&#xff0c;延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp &#xff0c;边缘服务器拉流推送到云服务器 …...