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

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: 30data1: 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.mrgr.cn/news/69441.html

相关文章:

  • Java项目:校园宿舍管理系统(优质版)(Springboot3+Maven+Mybatis Plus+Vue3+ Element Plus+Mysql)
  • 深度解析 Linux 系统下的 top 命令
  • Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
  • JVM 中的完整 GC 流程
  • 1 图的搜索 奇偶剪枝
  • 前端Vue项目启动报错,出现spawn cmd ENOENT的原因以及解决方案
  • Windows 11 安装 MySQL 8.4 LTS 详细安装配置教程(入门篇)
  • Cesium着色器的创意和方法(五——Polyline)
  • Linux中的用户创建及参数说明
  • nvm 切换 Node.js 版本
  • ElasticSearch向量检索技术方案介绍
  • Java异常处理
  • Android setContentView执行流程(一)-生成DecorView
  • AcWing 29:删除链表中重复的节点
  • 动态规划 —— dp 问题-买卖股票的最佳时机含冷冻期
  • Mysql基础 03 pymysql库、事务命令
  • 《Python编程实训快速上手》第四天--字符串操作
  • 【Java 多线程】:线程状态 线程操作 线程同步
  • Oracle OCP认证考试考点详解082系列17
  • 如何处理模型的过拟合和欠拟合问题
  • python可视化进阶
  • 科研绘图系列:R语言文章组合图形(barplot scatterplot)
  • Gen-RecSys——一个通过生成和大规模语言模型发展起来的推荐系统
  • 青藤深度参编的终端安全国家标准正式发布
  • 电商系统中,如何解决部分商品在短时间大量访问的单一热点问题?------Range范围分片
  • rce代码层面