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

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

本专栏目的

  • 更新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.kler.cn/a/386618.html

相关文章:

  • 进入未来城:第五周游戏指南
  • C# WPF FontDialog字体对话框,ColorDialog颜色对话框 引用
  • 必修 -- 常用笔试题
  • React中 修改 html字符串 中某些元素的属性
  • 基于碎纸片的拼接复原算法及MATLAB实现
  • 卓胜微嵌入式面试题及参考答案(2万字长文)
  • 解题--多数元素
  • Oracle RAC的thread
  • unity实习生面试
  • vite+vue项目创建流程;npm error enoent Could not read package.json异常报错问题
  • 表格全量数据下载(FileSaver和xlsx)
  • Mysql基础 03 pymysql库、事务命令
  • 多个NVR同时管理EasyNVR多品牌NVR管理工具/设备:IP常见问题解决方案
  • Ubuntu 安装yum遇坑
  • Android 重新定义一个广播修改系统时间,避免系统时间混乱
  • Redis 的线程模型
  • 【卷积基础】CNN中一些常见卷积(1*1卷积、膨胀卷积、组卷积、深度可分离卷积)
  • 快速学习Django框架以开发Web API
  • Django 框架:全方位技术分析
  • Linux如何更优质调节系统性能
  • 【网络安全 | 并发问题】Nginx重试机制与幂等性问题分析
  • 【问题解决】Tomcat由低于8版本升级到高版本使用Tomcat自带连接池报错无法找到表空间的问题
  • 论文阅读-Event-based Visible and Infrared Fusion via Multi-task Collaboration
  • 机器学习,生成式AI ,LLM大模型,人工智能,他们之间的关系是什么?有什么不同?
  • uni-app 实现自定义底部导航
  • 数据库的使用02:SQLServer的连接字符串、备份、还原、SQL监视相关设置