C/C++模板类模板与函数模板区别,以及用法详解
类模板
类模板语法
类模板作用:
- 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。
 
语法:
template<typename T>
类
 
解释:
template --- 声明创建模板
typename --- 表面其后面的符号是一种数据类型,可以用class代替
T --- 通用的数据类型,名称可以替换,通常为大写字母
示例:
#include <string>
//类模板
template<class NameType, class AgeType> 
class Person
{
public:Person(NameType name, AgeType age){this->mName = name;this->mAge = age;}void showPerson(){cout << "name: " << this->mName << " age: " << this->mAge << endl;}
public:NameType mName;AgeType mAge;
};
void test01()
{// 指定NameType 为string类型,AgeType 为 int类型Person<string, int>P1("孙悟空", 999);P1.showPerson();
}
int main() {
test01();
system("pause");
return 0;
}
 
总结:类模板和函数模板语法相似,在声明模板template后面加类,此类称为类模板
类模板与函数模板区别
类模板与函数模板区别主要有两点:
- 类模板没有自动类型推导的使用方式
 - 类模板在模板参数列表中可以有默认参数(只有类模板可以)
 
示例:
1、类模板没有自动类型推导的使用方式
#include <string>
//类模板
template<class NameType, class AgeType> 
class Person
{
public:Person(NameType name, AgeType age){this->mName = name;this->mAge = age;}void showPerson(){cout << "name: " << this->mName << " age: " << this->mAge << endl;}
public:NameType mName;AgeType mAge;
};
//1、类模板没有自动类型推导的使用方式
void test01()
{// Person p("孙悟空", 1000); // 错误 类模板使用时候,不可以用自动类型推导Person <string ,int>p("孙悟空", 1000); //必须使用显示指定类型的方式,使用类模板p.showPerson();
}
int main() {
test01();
system("pause");
return 0;
}
 
2、类模板在模板参数列表中可以有默认参数
#include <string>
//类模板
template<class NameType, class AgeType = int> //类模板在模板参数列表中可以有默认参数
class Person
{
public:Person(NameType name, AgeType age){this->mName = name;this->mAge = age;}void showPerson(){cout << "name: " << this->mName << " age: " << this->mAge << endl;}
public:NameType mName;AgeType mAge;
};
//2、类模板在模板参数列表中可以有默认参数
void test02()
{Person <string> p("猪八戒", 999); //类模板中的模板参数列表 可以指定默认参数p.showPerson();
}
int main() {
test02();
system("pause");
return 0;
}
 
 
总结:
- 类模板使用只能用显示指定类型方式
 - 类模板中的模板参数列表可以有默认参数
 
类模板中成员函数创建时机
类模板中成员函数和普通类中成员函数创建时机是有区别的:
- 普通类中的成员函数一开始就可以创建
 - 类模板中的成员函数在调用时才创建(ps:这一特性在类模板分文件编写时会产生问题)
 
示例:
class Person1
{
public:void showPerson1(){cout << "Person1 show" << endl;}
};
class Person2
{
public:void showPerson2(){cout << "Person2 show" << endl;}
};
template<class T>
class MyClass
{
public:T obj;
//下面两个成员函数可以编译成功,因为类模板中的成员函数,并不是一开始就创建的,而是在模板调用时再生成,不会报错。void fun1() { obj.showPerson1(); }void fun2() { obj.showPerson2(); }
};
void test01()
{MyClass<Person1> m;//可以编译成功,但是下面只能调用fun1(),调用fun2()报错m.fun1();
//m.fun2();//编译会出错,说明函数调用才会去创建成员函数
}
int main() {
test01();
system("pause");
return 0;
}
 
 
总结:类模板中的成员函数并不是一开始就创建的,因为无法确定数据类型,在调用时才去创建
类模板对象做函数参数
学习目标:
- 类模板实例化出的对象,向函数传参的方式
 
一共有三种传入方式:
- 指定传入的类型 --- 直接显示对象的数据类型
 - 参数模板化 --- 将对象中的参数变为模板进行传递
 - 整个类模板化 --- 将这个对象类型 模板化进行传递
 
示例:
#include <string>
//类模板
template<class NameType, class AgeType = int> 
class Person
{
public:Person(NameType name, AgeType age){this->mName = name;this->mAge = age;}void showPerson(){cout << "name: " << this->mName << " age: " << this->mAge << endl;}
public:NameType mName;AgeType mAge;
};
//1、指定传入的类型
void printPerson1(Person<string, int> &p) 
{p.showPerson();
}
void test01()
{Person <string, int >p("孙悟空", 100);printPerson1(p);
}
//2、参数模板化
template <class T1, class T2>
void printPerson2(Person<T1, T2>&p)
{p.showPerson();cout << "T1的类型为: " << typeid(T1).name() << endl;//查看该变量的数据类型cout << "T2的类型为: " << typeid(T2).name() << endl;
}
void test02()
{Person <string, int >p("猪八戒", 90);printPerson2(p);
}
//3、整个类模板化
template<class T>
void printPerson3(T & p)
{cout << "T的类型为: " << typeid(T).name() << endl;p.showPerson();
}
void test03()
{Person <string, int >p("唐僧", 30);printPerson3(p);
}
int main() {
test01();test02();test03();
system("pause");
return 0;
}
 
总结:
- 通过类模板创建的对象,可以有三种方式向函数中进行传参
 - 使用比较广泛是第一种:指定传入的类型
 
PS:查看数据类型函数typeip().name()
注意string类型返回值很长!
应用:
结合实际操作来看,第一种很常用,因为在传入之后只需要进行操作就行,不需要再考虑判定其是字符还是数字的问题。
第二种是保证其在一个类别中的万能性,比如你想对任意数据类型的数组作交换,但只想写一种函数,就可以用,但相对的会费脑子,在日常打代码一个复制粘贴改改就能写,但需要想的很远,等同于你象棋开局走一步就能达到到将死对面的所有情况你都要想,而且维护方面也是个问题,因此更常用的是第一种,以上还仅是在函数模板的基础上得到的结论,更别说在类模板的函数传入了。
第二种是将函数变为函数模板,目的是为了使用函数模板的自动类型指导。
第三种是直接将整个类模板作为一个类,2是将类模板里的类作为函数模板的类,2.3根本目的还是使用函数模板的自动类型推导
相关文章:
C/C++模板类模板与函数模板区别,以及用法详解
类模板 类模板语法 类模板作用: 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。 语法: template<typename T> 类解释: template --- 声明创建模板 typename --- 表面其后面的…...
van-dialog弹窗异步关闭-校验表单
van-dialog弹窗异步关闭 有时候我们需要通过弹窗去处理表单数据,在原生微信小程序配合vant组件中有多种方式实现,其中UI美观度最高的就是通过van-dialog嵌套表单实现。 通常表单涉及到是否必填,在van-dialog的确认事件中直接return是无法阻止…...
Dynamic Wallpaper 16.7中文版
Macos动态壁纸推荐: Dynamic Wallpaper是一款Mac平台上的动态壁纸应用程序,它可以根据时间等因素动态切换壁纸,提供更加生动和多样化的桌面体验。 Dynamic Wallpaper包含了多个动态壁纸,用户可以根据自己的喜好选择和切换。这些…...
如何使用ArcGIS Pro制作渐变河流效果
对于面要素的河流水系,制作渐变效果方法比较简单,如果是线要素的河流有办法制作渐变效果吗,答案是肯定的,这里为大家介绍一下制作方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的水系数…...
《网络协议》06. HTTP 补充 · HTTPS · SSL/TLS
title: 《网络协议》06. HTTP 补充 HTTPS SSL/TLS date: 2022-10-06 18:09:55 updated: 2023-11-15 07:53:52 categories: 学习记录:网络协议 excerpt: HTTP/1.1 协议的不足、HTTP/2、HTTP/3、HTTP 协议的安全问题、SPDY、HTTPS、SSL/TLS、OpenSSL。 comments: fa…...
Python winreg将cmd/PowerShell(管理员)添加到右键菜单
效果 1. 脚本 用管理员权限运行,重复执行会起到覆盖效果(根据sub_key)。 icon自己设置。text可以自定义。sub_key可以改但不推荐(避免改成和系统已有项冲突的)。command不要改。 from winreg import *registry r&q…...
redis运维(九)字符串(二)字符串过期时间
一 字符串过期时间 细节点: 注意命令的入参和返回值 ① 再谈过期时间 说明: 设置key的同时并且设置过期时间,是一个原子操作 ② ttl 检查过期时间 ③ persist 删除过期时间 ④ redis 删除过期key的机制 ⑤ 惰性删除 惰性理解:让过期…...
【C++】多线程的学习笔记(3)——白话文版(bushi
前言 好久没有继续写博客了,原因就是去沉淀了一下偷懒了一下 现在在学网络编程,c的多线程也还在学 这一变博客就讲讲c中的Condition Variable库吧 Condition Variable的简介 官方原文解释 翻译就是 条件变量是一个对象,它能够阻止调用…...
kotlin--3.集合操作
目录 一.list集合 二.Set集合 三.Map集合 迭代遍历Map集合: 8.hashMap 四.Stream流 1.map 2.filter 3.reduce 4.forEach 5.sorted 6.distinct 7.综合案例 一.list集合 在Kotlin中,常见的List集合类型有以下几种: listOf&…...
自动驾驶-BEV感知综述
BEV感知综述 随着自动驾驶传感器配置多模态化、多源化,将多源信息在unified View下表达变得更加关键。BEV视角下构建的local map对于多源信息融合及理解更加直观简洁,同时对于后续规划控制模块任务的开展也更为方便。BEV感知的核心问题是: …...
面试题-3
1.说一下原型链 原型就是一个普通对象,它是为构造函数实例共享属性和方法,所有实例中引用原型都是同一个对象 使用prototype可以把方法挂载在原型上,内存值保存一致 _proto_可以理解为指针,实例对象中的属性,指向了构造函数的原型(prototype) 2.new操…...
C++ Core Guidelines 中文版 GSL
C GSL(Guideline Support Library)是由 Microsoft 开发的一个开源库,旨在提供一组通用的 C 标准库扩展,以支持 C 标准委员会提出的指导原则。GSL 为 C 开发人员提供了许多有用的工具和类型,以帮助他们编写更安全、更高…...
同时显示上下两层凸包特征的可视化程序
数据类型 std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> hulls_k_upper std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> hulls_k_lower std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> hulls_underk_upper std::vector<…...
Django框架之模型层(二)
【十二】Django中如何开启事务 事务是MySQL数据库中得一个重要概念 事务的目的:为了保证多个SQL语句执行成功,执行失败,前后保持一致,保证数据安全 【1】ACID是数据库事务的四个关键特性 它代表了原子性(Atomicity)、…...
C++之list
C之list list的构造 #include <iostream> #include<list> using namespace std;//打印函数 void printfList(const list<int>&L) {for(list<int>::const_iterator it L.begin();it ! L.end();it){cout<<*it<<" ";}cout<…...
C语言日记——调试篇
一、调试调试的基本步骤 发现程序错误的存在 以隔离、消除等方式对错误进行定位 确定错误产生的原因 提出纠正错误的解决办法 对程序错误予以改正,重新测试 二、Debug和Release Debug通常称为调试版本,它包含调试信息,并且不作任何优化…...
【python】Django——templates模板、静态文件、django模板语法、请求和响应
笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ 【Django专栏】 Django——django简介、django安装、创建项目、快速上手 Django——templates模板、静态文件、django模板语法、请求和响应 Django——连接mysql数据库 Django——templates模板、静态文件、djang…...
Android设计模式--观察者模式
时间是一只藏在黑暗中温柔的手,在你一出神一恍惚之间,物走星移 一,定义 观察者模式是定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新 字面意思很好理解&am…...
【Linux】Ubuntu16.04下安装python高版本--源码安装
Ubuntu16.04下完美安装python高版本及对应版本的pip 方法一:直接用命令安装python3.6(但我没安装成功) 好像是因为Ubuntu16.04的软件仓库(源)中python的最高版本就是python3.5,所以无法直接用apt来安装 #方法一 sudo…...
变长子网划分问题的二叉树解法
计网的变长子网划分、计组的变长操作码划分、数据结构的哈夫曼编码,都是前缀编码的本质(变长操作码的二叉树解法我还在琢磨中) 【二叉树解法】每条从叶结点到根节点的路径上有且只有一个被分配的结点: 【例】现将一个IP网络划分成…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...
「Java基本语法」变量的使用
变量定义 变量是程序中存储数据的容器,用于保存可变的数据值。在Java中,变量必须先声明后使用,声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例:声明与初始化 public class VariableDemo {publi…...
AI书签管理工具开发全记录(十八):书签导入导出
文章目录 AI书签管理工具开发全记录(十八):书签导入导出1.前言 📝2.书签结构分析 📖3.书签示例 📑4.书签文件结构定义描述 🔣4.1. 整体文档结构4.2. 核心元素类型4.3. 层级关系4.…...
安宝特案例丨寻医不再长途跋涉?Vuzix再次以AR技术智能驱动远程医疗
加拿大领先科技公司TeleVU基于Vuzix智能眼镜打造远程医疗生态系统,彻底革新患者护理模式。 安宝特合作伙伴TeleVU成立30余年,沉淀医疗技术、计算机科学与人工智能经验,聚焦医疗保健领域,提供AR、AI、IoT解决方案。 该方案使医疗…...
Vuex:Vue.js 应用程序的状态管理模式
什么是Vuex? Vuex 是专门为 Vue.js 应用程序开发的状态管理模式 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 在大型单页应用中,当多个组件共享状态时,简单的单向数据流…...
