C/C++语言基础--C++模板与元编程系列四(类型模板参数、整数、指针 、模板类型)

news2024/11/13 11:12:44

本专栏目的

  • 更新C/C++的基础语法,包括C++的一些新特性

前言

  • 模板与元编程是C++的重要特点,也是难点,本人预计将会更新10期左右进行讲解,这是第四期,有些和前面三期重合,这一期也是为明天更新打下基础
  • C语言后面也会继续更新知识点,如内联汇编;
  • 欢迎收藏 + 关注,本人将会持续更新。

模板参数

前三掌已经讲解了函数、类、变量模板以及他们的特性等等,这一小节模板参数讲解,有一部分是对前面知识点的提取,👁👁👁👁👁,这一小节主要讲解一下几个部分:

  • 类型模板参数
  • 整数
  • 指针
  • 模板类型

💁‍♂ 注意:,模板这个东西比较新,本人是在C++20的标准下进行学习的。

类型模板参数

☄ 这个是最常用的,就是用typename关键字定义的类型,如下:

template <typename T>
void show(T t)
{
	std::cout << "t: " << t << std::endl;
}

⭕️ 其中T可以是任意类型参数,如下显示:

show<int>(50);
show<void*>(nullptr);
show<std::string>("HelloWorld");

/*结果:
t: 50
t: 0000000000000000
t: HelloWorld
*/

其他,还可以结合**const、&**等结合,如下代码:

#include <iostream>
#include <type_traits>

template <typename T>
void show(T& t)
{
	std::cout << "t: " << t << std::endl;
	// 判断是否为 int 类型
	if (std::is_same_v<T, int>) {
		t = 100;
	}
}

int main()
{
	int a = 50;
	show<int>(a);
	std::cout << "a: " << a << std::endl;

	return 0;
}

这段代码中,变量类型使用&修饰,说明这个是引用传递,结果如下:

在这里插入图片描述

🚿 概括:进一步说明了,模板参数兼容任意类型。

整型

整型:比如说intshortcharbool类型等,C++20后,可以支持double

这个部分前三章讲过,这里就不详细讲解了,总的来说就是,不用typename声明类型,直接用int、short、size_t等类型直接声明,如下:

template <size_t size>
void print()
{
	std::cout << "size: " << size << std::endl;
}

int main()
{
	print<100>();   // 直接打印

	return 0;
}

结果

在这里插入图片描述


🚯🚯🚯🚯🚯 注意

模板是在编译的时候计算出来的,如果传递的是不是在编译的时候编译出来的东西,就会报错,如下代码:

template <size_t size>
void print()
{
	std::cout << "size: " << size << std::endl;
}

int main()
{
	std::vector<int> temp{ 1, 2, 3, 4, 5 ,6 ,7 };
	print<temp.size()>();

	return 0;
}

🚻 结果

在这里插入图片描述

原因.size()方法是在运行的时候确定的,不是在编译期间。

指针

变量指针这个当然可以,上面案例也有,这里讲解函数指针的情况,模板参数,还可以作为函数指针,代码如下:

template <typename T>
void add(T a, T b)
{
	std::cout << "a + b: " << a + b << std::endl;
}

/// 函数指针作为参数
template <typename T, void (*add)(T a, T b)>
void add_num(T a, T b)
{
	add(a, b);
}

int main()
{
	add_num<int, add<int>>(20, 30);


	return 0;
}

结果:

在这里插入图片描述

模板嵌套类型

关键点在于大家自己要清楚类型如何表示(类型是由类名<类型>表示一个类型)

来个案例

#include <iostream>

template<typename T1, typename T2, typename T3>
class Data
{
public:
	Data(T1 t1, T2 t2, T3 t3) : m_data1(t1), m_data2(t2), m_data3(t3) {}

	void print()
	{
		std::cout << "m_data1: " << m_data1 << " m_data2: " << m_data2 << " m_data3: " << m_data3 << std::endl;
	}

private:
	T1 m_data1;
	T2 m_data2;
	T3 m_data3;
};

template<typename T1, typename T2>
class Info
{
public:
	Info(T1 t1, T2 t2) : m_data1(t1), m_data2(t2) {}

	void print()
	{
		std::cout << "data1: " << m_data1 << " data2: " << m_data2 << std::endl;
	}
private:
	T1 m_data1;
	T2 m_data2;
};

int main()
{
	Data<int, int, int> data(10, 20, 30);
	data.print();

	Info<int, int> info1(50, 60);
	info1.print();
	
    /*
    m_data1: 10 m_data2: 20 m_data3: 30
	data1: 50 data2: 60
    */

	return 0;
}

💇 上面案例就是很简单的案例,定义了两个案例模板,后买你定义了一个打印数据的函数;

👔 现在需求将模板类作为参数,代码如下:

	Info<Data<int, int, int>, Data<std::string, std::string, std::string>> info2(Data<int, int, int>(66, 77, 88), Data<std::string, std::string, std::string>("w", "y", "z"));
	
	info2.print();

这个时候运行

在这里插入图片描述

报错了: 原因原容易找到,这个在之前的运算符重载又讲(C/C++语言基础–C++运算符重载以及其重载限制-CSDN博客),只需要加个运算符重载即可。

template<typename T1, typename T2, typename T3>
class Data
{
public:
	Data(T1 t1, T2 t2, T3 t3) : m_data1(t1), m_data2(t2), m_data3(t3) {}

	void print()
	{
		std::cout << "m_data1: " << m_data1 << " m_data2: " << m_data2 << " m_data3: " << m_data3 << std::endl;
	}
	// 运算符从在即可
	friend std::ostream& operator<<(std::ostream& out, const Data& data) {
		out << data.m_data1 << " " << data.m_data2 << " " << data.m_data3 << "\n";
		return out;
	}

private:
	T1 m_data1;
	T2 m_data2;
	T3 m_data3;
};

结果:

data1: 66 77 88
data2: w y z

核心: 要注意数据如何表示,输出的时候如何输出,即可;

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

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

相关文章

数据结构:顺序表(动态顺序表)

专栏说明&#xff1a;本专栏用于数据结构复习&#xff0c;文章中出现的代码由C语言实现&#xff0c;在专栏中会涉及到部分OJ题目&#xff0c;如对你学习有所帮助&#xff0c;可以点赞鼓励一下博主喔&#x1f493; 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;数…

力扣动态规划基础版(矩阵型)

62.不同路径&#xff08;唯一路径问题&#xff09; 62. 不同路径https://leetcode.cn/problems/unique-paths/ 方法一&#xff1a;动态规划 找状态转移方程&#xff0c;也就是说它从左上角走到右下角&#xff0c;只能往右或者往下走&#xff0c;那么设置一个位置为&#xff…

音视频入门基础:FLV专题(23)——FFmpeg源码中,获取FLV文件音频信息的实现(下)

音视频入门基础&#xff1a;FLV专题系列文章&#xff1a; 音视频入门基础&#xff1a;FLV专题&#xff08;1&#xff09;——FLV官方文档下载 音视频入门基础&#xff1a;FLV专题&#xff08;2&#xff09;——使用FFmpeg命令生成flv文件 音视频入门基础&#xff1a;FLV专题…

A021基于Spring Boot的自习室管理和预约系统设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

qt QShortcut详解

1、概述 QShortcut是Qt框架中的一个类&#xff0c;它提供了一种创建键盘快捷键的方式。通过QShortcut&#xff0c;开发者可以将特定的键盘组合&#xff08;如CtrlC、AltF4等&#xff09;与应用程序中的动作&#xff08;如复制、关闭窗口等&#xff09;关联起来。当用户在应用程…

注意力机制的目的:理解语义;编码器嵌入高纬空间计算;注意力得分“得到S*V”;解码器掩码和交叉注意力层用于训练;最终的编码器和输出实现大模型

目录 注意力机制的目的:理解语义中的它是小白兔 词编码器嵌入高纬空间 计算注意力得分“得到S*V” 权重QKV:连接权重 训练阶段使用解码器:翻译后的语句 解码器掩码和交叉注意力层用于训练 最终的编码器和输出实现大模型 Transformer模型中,QKV QKV的作用 举例说明…

jmeter常用配置元件介绍总结之取样器

系列文章目录 1.windows、linux安装jmeter及设置中文显示 2.jmeter常用配置元件介绍总结之安装插件 3.jmeter常用配置元件介绍总结之取样器 jmeter常用配置元件介绍总结之取样器 2.取样器2.1.HTTP请求2.2.Debug Sampler2.3.JSR223 Sampler2.4.JDBC Connection Configuration和J…

【大数据学习 | kafka】简述kafka的消费者consumer

1. 消费者的结构 能够在kafka中拉取数据进行消费的组件或者程序都叫做消费者。 这里面要涉及到一个动作叫做拉取。 首先我们要知道kafka这个消息队列主要的功能就是起到缓冲的作用&#xff0c;比如flume采集数据然后交给spark或者flink进行计算分析&#xff0c;但是flume采用的…

从零开始训练一个大语言模型需要多少天?

一&#xff0c;前言 在AI领域&#xff0c;训练一个大型语言模型&#xff08;LLM&#xff09;是一个耗时且复杂的过程。几乎每个做大型语言模型&#xff08;LLM&#xff09;训练的人都会被问到&#xff1a;“从零开始&#xff0c;训练大语言模型需要多久和花多少钱&#xff1f;”…

【SQL50】day 1

目录 1.可回收且低脂的产品 2.寻找用户推荐人 3.使用唯一标识码替换员工ID 4.产品销售分析 I 5.有趣的电影 6.平均售价 7.每位教师所教授的科目种类的数量 8.平均售价 1.可回收且低脂的产品 # Write your MySQL query statement below select product_id from Products w…

Qt菜单功能实现

本文介绍Qt菜单功能实现。 Qt开发过程中&#xff0c;菜单功能用的还是比较多的&#xff0c;本文针对菜单栏和右键菜单功能实现作简要描述。 1.菜单栏 1)界面设计 在界面中添加菜单栏&#xff08;本例中名为“menubar”&#xff09;&#xff0c;并依次添加需要的菜单&#x…

Jupyter Notebook添加kernel的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Java:二维数组

目录 1. 二维数组的基础格式 1.1 二维数组变量的创建 —— 3种形式 1.2 二维数组的初始化 \1 动态初始化 \2 静态初始化 2. 二维数组的大小 和 内存分配 3. 二维数组的不规则初始化 4. 遍历二维数组 4.1 for循环 ​编辑 4.2 for-each循环 5. 二维数组 与 方法 5.1…

手机内卷下一站,AI Agent

作者 | 辰纹 来源 | 洞见新研社 2024年除夕夜&#xff0c;OPPO在央视春晚即将开始前举办了一场“史上最短发布会”&#xff0c;OPPO首席产品官刘作虎宣布&#xff0c;“OPPO正式进入AI手机时代”。 春节假期刚过&#xff0c;魅族又公开表示&#xff0c;将停止“传统智能手机…

Python实战:调用淘宝API以抓取商品页面数据

在数据驱动的商业决策中&#xff0c;获取电商平台的商品数据至关重要。淘宝作为中国最大的在线购物平台&#xff0c;其商品数据对于市场分析、价格监控和竞品研究等方面都具有极高的价值。本文将通过一个Python实战案例&#xff0c;展示如何调用淘宝API来抓取商品页面的数据。 …

SpringBoot14-任务

任务 14.1异步任务 所谓异步&#xff0c;在某些功能实现时可能要花费一定的时间&#xff0c;但是为了不影响客户端的体验&#xff0c;选择异步执行 案例&#xff1a; 首先创建一个service&#xff1a; Service public class AsyncService {public void hello(){try {Threa…

如何在Android中自定义property

在Android中创建自定义的属性&#xff08;Android property&#xff09;通常用于调试、性能调优或传递应用和系统之间的信息。 以下是如何在Android中创建和使用自定义属性的步骤&#xff1a; 1. 定义属性 在Android中&#xff0c;属性是以“属性名称属性值”形式定义的键值对…

SSH实验5密钥登录Linuxroot用户(免密登录)

当用户尝试通过SSH连接到远程服务器时&#xff0c;客户端会生成一对密钥&#xff1a;公钥和私钥。公钥被发送到远程服务器&#xff0c;并存储在服务器的~/.ssh/authorized_keys文件中。而私钥则由客户端保管&#xff0c;不会传输给服务器。 在连接过程中&#xff0c;客户端使用…

CelebV-Text——从文本生成人脸视频的数据集

概述 近年来&#xff0c;生成模型在根据文本生成和编辑视频方面受到了广泛关注。然而&#xff0c;由于缺乏合适的数据集&#xff0c;生成人脸视频领域仍然是一个挑战。特别是&#xff0c;生成的视频帧质量较低&#xff0c;与输入文本的相关性较弱。在本文中&#xff0c;我们通…

天地图入门|标注|移动飞行|缩放,商用地图替换

“天地图”是国家测绘地理信息局建设的地理信息综合服务网站。集成了来自国家、省、市&#xff08;县&#xff09;各级测绘地理信息部门&#xff0c;以及相关政府部门、企事业单位 、社会团体、公众的地理信息公共服务资源&#xff0c;如果做的项目是政府部门、企事业单位尽量选…