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

C++ 模板学习笔记

C++另外一种编程成为 泛型编程 ,主要利用的技术就是模板
C++提供两种模板机制:函数模板和类模板

C++11中,函数模板和类模板都可以设定默认参数,传送门

函数模板

一般 typenameclass 没有区别,typename 还有个作用是使用嵌套依赖类型

template <class 类型参数1, class类型参数2, ...>
返回值类型  模板名(形参表)
{函数体
}
template<class T> 
void MySwap(T &a, T &b) {
}
template<class T>
void fun() {cout << "fun函数调用" << endl;
}
void test() {int a = 10, b = 20;char c = 'x'// 1 自动类型推导MySwap(a, b);//MySwap(a, c);    //  错误,无法推导出同一T类型// 2 显示指定类型MySwap<int>(a, b);// 3.模板必须确定出T的类型才能使用//fun();  错误,无法自动推导出T的类型fun<int>();
}
  1. 自动类型推导必须推导出一致的数据类型 T,才可以使用
  2. 模板必须要确定出 T 的数据类型,才能使用

普通函数与函数模板的区别

  1. 普通函数调用时参数可以发生自动类型转换(隐式类型转换)
  2. 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换(无法推导出同一类型T);如果使用显示指定类型的方式,就可以发生隐式类型转换

比如传入类型为char的参数自动转换为 int

普通函数与函数模板的调用规则

void myPrint(int a, int b){}template<typename T>
void myPrint(T a, T b){}template<typename T>
void myPrint(T a, T b, T c){}void test01()
{
//1、如果函数模板和普通函数都可以实现,优先调用普通函数
// 注意 如果告诉编译器 普通函数是有的,但只是声明没有实现,或者不在当前文件内实现,就会报错找不到int a = 10;int b = 20;myPrint(a, b); //调用普通函数//2、可以通过空模板参数列表来强制调用函数模板myPrint<>(a, b); //调用函数模板//3、函数模板也可以发生重载int c = 30;myPrint(a, b, c); //调用重载的函数模板//4、 如果函数模板可以产生更好的匹配,优先调用函数模板char c1 = 'a';char c2 = 'b';myPrint(c1, c2); //调用函数模板
}

为特定的类型提供具体化的模板

class Person{public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}string m_Name;int m_Age;
};
//普通函数模板
template<class T>
bool myCompare(T& a, T& b)
{if (a == b) return true;return false;
}
//具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
//具体化优先于常规模板
template<> bool myCompare(Person &p1, Person &p2)
{if ( p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age) return true;return false;
}
void test() {int a = 10, b = 20;bool ret1 = myCompare(a, b); //内置数据类型可以直接使用通用的函数模板Person p1("Tom", 10), p2("Tom", 10); //自定义数据类型,不会调用普通的函数模板//可以创建具体化的Person数据类型的模板,用于特殊处理这个类型bool ret2 = myCompare(p1, p2);
}

类模板

类模板作用:建立一个通用类,类中的成员数据类型可以不具体制定,用一个虚拟的类型来代表。

template <class 类型参数1, class类型参数2, ...>
class  类模板名(形参表)
{类实现
}
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(){// Person p("孙悟空", 1000); // 错误 类模板使用时候,不可以用自动类型推导Person<string, int>P1("孙悟空", 999);// 指定NameType 为string类型,AgeType 为 int类型Person <string> p("猪八戒", 999); //类模板中的模板参数列表 可以指定默认参数
}

类模板与函数模板区别主要有两点:

  1. 类模板没有自动类型推导的使用方式,只能用显示指定类型方式
  2. 类模板在模板参数列表中可以有默认参数

类模板中成员函数创建时机

类模板中成员函数和普通类中成员函数创建时机是有区别的:

  1. 普通类中的成员函数一开始就可以创建
  2. 类模板中的成员函数在调用时才创建

类模板对象做函数参数

template<class NameType, class AgeType = int>
class Person
{
public:Person(NameType name, AgeType age){this->mName = name;this->mAge = age;}
public:NameType mName;AgeType mAge;
};
//1、指定传入的类型,普通函数
void printPerson1(Person<string, int>& p) {}
void test01()
{Person <string, int >p("孙悟空", 100);printPerson1(p);
}
//2、使用函数模板,将类模板的参数模板化  
template <class T1, class T2>
void printPerson2(Person<T1, T2>& p)
{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;
}
void test03()
{Person <string, int >p("唐僧", 30);printPerson3(p);
}

类模板案例

案例描述: 实现一个通用的数组类,要求如下:

  1. 可以对内置数据类型以及自定义数据类型的数据进行存储
  2. 将数组中的数据存储到堆区
  3. 构造函数中可以传入数组的容量
  4. 提供对应的拷贝构造函数以及operator=防止浅拷贝问题
  5. 提供尾插法和尾删法对数组中的数据进行增加和删除
  6. 可以通过下标的方式访问数组中的元素
  7. 可以获取数组中当前元素个数和数组的容量
#include "myArray.hpp"
#include <string>
#include <iostream>// 1. 内置数据类型
void printInt(myarr<int>& arr) {for (int i = 0; i < arr.getSize(); ++i) {cout << arr[i] << " ";}cout << endl;
}
void test1() {myarr<int> v(10);for (int i = 0; i < 10; ++i) {v.Push_back(i * i);}printInt(v);
}// 2. 自定义数据类型
class Person {
public:Person() {}Person(string name, int age) {this->name = name;this->age = age;}string name;int age;
};
void printPerson(myarr<Person>& arr) {for (int i = 0; i < arr.getSize(); ++i) {cout << arr[i].name << " " << arr[i].age << endl;}
}
void test2() {Person a("fu1", 20), b("fu2", 22), c("fu3", 24);Person d("p1", 11), e("p2", 14);myarr<Person> v(10);v.Push_back(a); v.Push_back(b); v.Push_back(c);v.Push_back(d); v.Push_back(e);printPerson(v);
}
int main() {test1();test2();return 0;
}

相关文章:

C++ 模板学习笔记

C另外一种编程成为 泛型编程 &#xff0c;主要利用的技术就是模板 C提供两种模板机制&#xff1a;函数模板和类模板 C11中&#xff0c;函数模板和类模板都可以设定默认参数&#xff0c;传送门 函数模板 一般 typename 和 class 没有区别&#xff0c;typename 还有个作用是使…...

1、Flink基础概念

1、基础知识 &#xff08;1&#xff09;、数据流上的有状态计算 &#xff08;2&#xff09;、框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行有状态计算。 &#xff08;3&#xff09;、事件驱动型应用&#xff0c;有数据流就进行处理&#xff0c;无数据流就不…...

分享一下怎么做小程序营销活动

小程序营销活动已经成为现代营销的必备利器&#xff0c;它能够帮助企业提高品牌知名度、促进产品销售&#xff0c;以及加强与用户的互动。然而&#xff0c;要想成功地策划和执行一个小程序营销活动&#xff0c;需要精心设计和全面规划。本文将为您介绍小程序营销活动的策划和执…...

Laravel 后台管理 Dcat Admin 使用记录

Laravel Dcat Admin 安装配置修改配置表格操作 Ajax 结合 Pjax 更新数据状态表格 链接表单设置页面(通常修改更新在同一页面)表单 安装配置 安装文档地址 框架版本 Laravel 8.* 修改配置 修改 admin.php 文件 return [// 后台名称name > DAD后台管理,// 标题title > 后台…...

c语言基础:L1-070 吃火锅

以上图片来自微信朋友圈&#xff1a;这种天气你有什么破事打电话给我基本没用。但是如果你说“吃火锅”&#xff0c;那就厉害了&#xff0c;我们的故事就开始了。 本题要求你实现一个程序&#xff0c;自动检查你朋友给你发来的信息里有没有 chi1 huo3 guo1。 输入格式&#x…...

java spring boot 注解、接口和问题解决方法(持续更新)

注解 RestController 是SpringMVC框架中的一个注解&#xff0c;它结合了Controller和ResponseBody两个注解的功能&#xff0c;用于标记一个类或者方法&#xff0c;表示该类或方法用于处理HTTP请求&#xff0c;并将响应的结果直接返回给客户端&#xff0c;而不需要进行视图渲染…...

HMAC_SHA1加密算法和SHA1加密算法的区别

HMAC_SHA1加密算法和SHA1加密算法的区别 应用场景&#xff1a;SHA1目前主要用于政府部门和私营业主处理敏感信息&#xff0c;被视为最先进的加密技术。而HMAC_SHA1主要用于基于密钥的消息认证码&#xff08;HMAC&#xff09;运算&#xff0c;需要一个密钥作为输入。密钥需求&a…...

Ubuntu连不上WiFi 或者虽然能连上校园网,但是浏览器打不开登录页面

写在前面 自己的电脑环境&#xff1a; Ubuntu20.04 一、问题描述 自己的 Ubuntu 遇到连接不上 除校园网之外的其他WiFi, 或者 虽然能连上校园网&#xff0c;但是浏览器打不开登录页面的问题。 二、解决方法 出现这种问题的原因可能是 之前开过VPN, 导致系统的网络设置出现…...

Maven第八章:如何解决Maven的jar版本冲突

Maven第八章:如何解决Maven的jar版本冲突 前言 本文重点讲解Maven依赖冲突原因,maven依赖原则以及如何利用idea Maven Helper插件分析解决问题。 背景 开发过程中引入第三方jar遇到依赖冲突的,非常影响开发,甚至大部分时间都在调试版本兼容。 Caused by:java.lang.NoSuch…...

c# 读写内存映射文件

在C#中&#xff0c;可以使用System.IO.MemoryMappedFiles命名空间中的MemoryMappedFile类来操作内存映射文件。可以创建不固定大小的内存映射文件&#xff0c;具体步骤如下&#xff1a; 1. 先创建一个初始大小为0的内存映射文件&#xff0c;使用MemoryMappedFile.CreateNew方法…...

行业揭秘:腾讯共享wifi码推广零加盟费是真的吗?

近年来&#xff0c;“共享经济”概念在商业领域取得了巨大成功。共享WiFi贴码成为共享经济的一种典型案例&#xff0c;被越来越多的人看作是一种低风险、高回报的投资方式。而在这个市场中&#xff0c;腾讯WiFi码推广以“零加盟费”而备受关注。本文将探讨腾讯WiFi码推广零加盟…...

E4980A 精密型 LCR 表,20 Hz 至 2 MHz

E4980A 精密型 LCR 表 20 Hz 至 2 MHz E4980A 精密型 LCR 表实现了测量准确度、速度与通用性的理想结合&#xff0c;适用于各种元器件测量。 E4980A 精密型 LCR 表实现了测量准确度、速度与通用性的理想结合&#xff0c;适用于各种元器件测量。 无论是在低阻抗量程还是在高阻…...

【前端工作提效】关于工作提效的一点实践与思考

1、测试提的BUG是一个一个提的&#xff0c;如果顺着测试提供的BUG单去一个一个解决问题&#xff0c;那么很容易管中窥豹&#xff0c;就像打补丁一样&#xff0c;缝缝补补&#xff0c;没有办法从根源去解决问题。所以我们需要尽量去了解代码的业务情况&#xff0c;并尽可能将一些…...

Pytorch 文本情感分类案例

一共六个脚本,分别是: ①generateDictionary.py用于生成词典 ②datasets.py定义了数据集加载的方法 ③models.py定义了网络模型 ④configs.py配置一些参数 ⑤run_train.py训练模型 ⑥run_test.py测试模型 数据集https://download.csdn.net/download/Victor_Li_/88486959?spm1…...

Flutter之GetX controller tag使用详解

本文主要介绍 GetX 依赖注入中 tag 的作用和使用详解。 作用 前面几篇文章介绍了 GetX 依赖注入的使用以及通过源码剖析了依赖注入的原理&#xff1a; •《Flutter应用框架搭建(一)GetX集成及使用详解》•《Flutter 通过源码一步一步剖析 Getx 依赖管理的实现》•《Flutter之…...

Kubernetes群集调度

调度约束 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件&#xff0c;向 APIServer 发送命令&#xff0c;在 Node 节点上面建立 Pod 和 Container。 APIServ…...

【总结】linux centos 7 开启网络白名单访问策略

目录 linux开启网络端口白名单访问策略开启白名单步骤补充说明 linux开启网络端口白名单访问策略 安全需要&#xff0c;被检测各种3306、9200、9300端口没有设置访问策略。需要整改。 对于linux来说&#xff0c;有两种方式可以开启防火墙 开启白名单步骤 场景一&#xff1a…...

2023-2024-1高级语言程序设计第1次月考

7-1-1 计算摄氏温度 给定一个华氏温度F&#xff0c;本题要求编写程序&#xff0c;计算对应的摄氏温度C。计算公式&#xff1a;C5(F−32)/9。题目保证输入与输出均在整型范围内。 输入格式: 输入在一行中给出一个华氏温度。 输出格式: 在一行中按照格式“Celsius C”输出对…...

目标检测:Proposal-Contrastive Pretraining for Object Detection from Fewer Data

论文作者&#xff1a;Quentin Bouniot,Romaric Audigier,Anglique Loesch,Amaury Habrard 作者单位&#xff1a;Universit Paris-Saclay; Universit Jean Monnet Saint-Etienne; Universitaire de France (IUF) 论文链接&#xff1a;http://arxiv.org/abs/2310.16835v1 内容…...

Cesium:CGCS2000坐标系的xyz坐标转换成WGS84坐标系的经纬高度,再转换到笛卡尔坐标系的xyz坐标

作者:CSDN @ _乐多_ 本文将介绍使用 Vue 、cesium、proj4 框架,实现将CGCS2000坐标系的xyz坐标转换成WGS84坐标系的经纬高度,再将WGS84坐标系的经纬高度转换到笛卡尔坐标系的xyz坐标的代码。并将输入和输出使用 Vue 前端框架展示了出来。代码即插即用。 网页效果如下图所示…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...