C++ —— 模板的基本概念和使用

news2025/1/20 3:52:07

目录

1.函数模板是什么

1.1函数模板的基本概念

1.2函数模板的基本使用

1.3函数模板的特化

1.4非类型模板参数

2.类模板是什么

2.1类模板的基本使用

2.2非类型模板参数

2.3类模板的特化

2.4模板特化后的优先级

3.函数模板不要分离编译

1.函数模板是什么

模板是一种泛型编程,我们处理数据时可以忽略这些数据的类型。在C语言的编程当中,定义一个swap交换函数只能交换给定的参数类型的数据;但如果使用C++的模板定义函数,就可以忽略这些类型。

template <class T>
void swap(const T& x, const T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

1.1函数模板的基本概念

模板的关键字为 template 加一对尖括号。尖括号里面是类型(并没有指定)的名字,可以使用关键字 class 或者 typename 命名。它的作用域就是从此行开始往下找的第一个函数。当我们调用这个模板函数的时候,编译器会根据我们的实参推演出模板函数的参数类型,然后完成实例化生成一份具体的函数(也就是说,模板函数不是一个具体的函数)。

尖括号里面的参数可以是一个或者多个。如果确实需要多个参数,那么这些参数的命名不能相同(也就是说一个参数对应一个类型)。

1.2函数模板的基本使用

我们以这个函数模板为例:

template<class T1,typename T2>
void Print(const T1& x, const T2& y)
{
	//获取模板参数的类型
	cout << typeid(T1).name() << " " << typeid(T2).name() << endl;
}

第一种用法:让实参推演出模板的参数类型。

	Print(1, 2);
	Print(3.14, 2);
	Print("abc", 'a');

第二种用法:显式实例化模板参数(如果实参的类型与模板参数有冲突,能进行强制类型转换就进行强制类型转换,否则报错)。

	Print<int, int>(3.14, 2);
	Print<string, char>("abc", 'b');
	Print<string, int>(1.25, 2);	//无法类型转换,报错

1.3函数模板的特化

还是以上面的函数模板为例。

如果想对某些类型进行特殊处理(例如都传入int类型的参数时,不执行打印类型的操作,而执行打印数据的值),需要用到模板的特化。特化分为全特化和半特化。

全特化的格式如下:

template<>
void Print<int,int>(const int& x, const int& y)
{
	cout << "x = " << x << " y = " << y << endl;
}

函数模板没有偏特化,偏特化将会在介绍类模板时讲到。

1.4非类型模板参数

模板的参数并不一定代表某一类型,还可以作为非类型参数。

template<size_t N>
void test()
{
	cout << N << endl;
}

注意调用此函数时,模板参数 N 是通过显式实例化得到的,而不是通过调用函数时传递的实参。

2.类模板是什么

没有模板之前,设计类时往往只能针对一种类型。但有了模板之后,类的设计更加泛型化。

namespace ly
{
	template<class T>
	class stack
	{
	public:

	private:
		T* _a;		//我们可以自定义栈存储什么类型的数据
	};
}

2.1类模板的基本使用

类模板的使用必须显式实例化!并且类模板的类名不代表一个类(也就是不代表某种自定义类型),只有当类模板实例化之后的类名才代表一个类(也就是代表了一种自定义类型)。

	ly::stack<int> st;
	ly::stack<char> st;
	ly::stack<double> st;

2.2非类型模板参数

非类型模板参数用在类模板当中是一种典型用法。非类型模板参数还可以给缺省值(模板参数都可以给缺省值)。

template<class T,size_t N = 10>
class Arr
{
public:

private:
	T _a[N];
};

2.3类模板的特化

类模板可以有全特化和半特化。与函数模板一样,模板根据我们显式实例化提供的参数推导出模板的类型,然后生成一份具体的类。但是如果我们想对某些类型进行特殊的处理,就可以使用特化。

我们以这个类为例:

template <class T1,class T2>
class test
{
public:
	test()
	{
		//不管传入任何类型,最终都打印:
		cout << "test<T1,T2>" << endl;
	}
};

全特化的格式如下:

template <>
class test<int,int>
{
public:
	test()
	{
		//当传入的类型都为int时,单独打印:
		cout << "test<int,int>" << endl;
	}
};

半特化(也叫偏特化)的格式如下:

template <class T1>
class test<T1, char>
{
public:
	test()
	{
		//模板参数的第二个类型为char时,打印:
		cout << "test<T1,char>" << endl;
	}
};

2.4模板特化后的优先级

全特化>半特化>无特化

3.函数模板不要分离编译

尽量在头文件中一起出现函数的声明和定义。因为将函数的声明放在头文件而定义放在其他源文件中会引发链接错误。

其原因就在于函数模板并不是一个真正的函数,当我们在一头文件包含了只有函数模板的声明的头文件时,编译器就会默认认为有这个函数(具体在哪由链接器去寻找),到了链接时,就会发生链接错误(因为函数模板不是函数)。

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

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

相关文章

python和MySQL的基础使用和数据的插入导出

一.基础使用第三方库pymysql除了使用图形化工具以外&#xff0c;我们也可以使用编程语言来执行SQL从而操作数据库。在Python中&#xff0c;使用第三方库:pymysql来完成对MySQL数据库的操作。安装创建到MySQL的数据库链接具体代码如下from pymysql import Connect #获取到MySQL数…

LVS+Keepalived+Nginx宏观整体结构与关键问答

视频链接&#xff1a;4-2 为什么要使用 LVS Nginx&#xff1f;_哔哩哔哩_bilibili ———————————————————————————————————————————————————————— 1. 问题&#xff1a; 为什么要使用LVS Nginx&#xff1f;&#xf…

C语言刮刮乐(掩码图的范例)

程序简介 这个程序模拟了刮刮乐的刮卡操作&#xff0c;按下鼠标左键并移动可以刮开刮卡层。 刮卡操作是通过掩码图实现的&#xff0c;一张隐藏的待刮开背景图&#xff0c;一张掩码图。 刮卡的时候&#xff0c;是在黑色的掩码图上画线&#xff0c;显示的时候&#xff0c;通过…

官方正品 | Ultralytics YOLOv8算法来啦(尖端SOTA模型)

&#x1f680;&#x1f680;&#x1f680;卷王之王 | Ultralytics YOLOv8 算法来啦&#xff01;&#xff01;✨✨✨ 一、前言简介 &#x1f384;&#x1f388; &#x1f4da; 代码地址&#xff1a;卷王之王 | YOLOv8代码下载地址 &#x1f4da; 详细文档&#xff1a;https://…

代码随想录算法训练营第十四天字符串 java :二叉树理论基础 144前序遍历 145后续遍历94 中序遍历

系列文章目录 第十一天笔记 文章目录系列文章目录前言1、二叉树理论基础1.1二叉树的种类1.1 如何区分二叉树的遍历方式1.2 如何定义二叉树节点2 递归遍历2.1**前序遍历 AC代码**2.2**后序遍历 AC代码**2.3 **中序遍历 AC代码**3 迭代法4 层次遍历总结**什么是List<List <…

组态王软件与S7-1200无线MODBUS通信方案详解

本方案是组态软件与西门子 S7-1200进行无线 MODBUS 通信的实现方法。此方案可以作为西门子 S7-1200与组态软件的无线 MODBUS 通信实例。在本方案中采用了西门子PLC专用无线通讯终端DTD434MC&#xff0c;作为实现无线通讯的硬件设备。 一、方案概述 组态王配置为标准 MODBUS 主…

基础面试问题

在Java中获取当前的工作目录System.getProperty("user.dir")public class Test {public static void main(final String[] args) {final String dir System.getProperty("user.dir");System.out.println("current dir " dir);} }获取一定范围…

Redis01之Windows版本的Redis安装配置

目录 0. 学习网址 https://www.w3cschool.cn/redis/https://www.w3cschool.cn/redis/ 1. Redis简介 2. 下载 3. 安装和配置 3.1 window(略...) 3.2 linux(CentOS) 4. Redis支持五种数据类型 5.通过命令操作redis 0. 学习网址 https://www.w3cschool.cn/redis/http…

一文搞懂CPU如何控制I/O设备

1 接口和设备&#xff1a;经典适配器模式 输入输出设备不只是一个设备。大部分输入输出设备&#xff0c;都有&#xff1a; 它的接口&#xff08;Interface&#xff09;实际的I/O设备&#xff08;Actual I/O Device&#xff09; 硬件设备并非直接接入到总线上和CPU通信&#…

UOS 录制电脑播放的音频 / 内录音频

Windows 里面有一个“立体声混音”&#xff0c;可以内录电脑播放的音频&#xff0c;而不受到外界噪音的干扰。前段时间接到反馈说 UOS 的设置里面的音频输入里面没有可以选择的设备&#xff0c;这里就稍微探索了一下&#xff0c;发现 UOS 也是可以配置内录的。这里参考了一下这…

网络基础(一)

网络基础&#xff08;一&#xff09;计算机网络背景网络发展独立模式: &#xff08;计算机之间相互独立&#xff09;网络互联: ( 多台计算机连接在一起, 完成数据共享)局域网LAN: (计算机数量更多了, 通过交换机和路由器连接在一起);广域网WAN: &#xff08;将远隔千里的计算机…

vue入门到精通(一)

一、vue简介 Vue是一款用于构建用户界面的 JavaScript 框架。 它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。 二、vue3选项式…

Linux编译器-gcc/g++使用

目录 1. 背景知识 2. gcc如何完成 2.1 预处理(进行宏替换) 2.2 编译&#xff08;生成汇编&#xff09; 2.3 汇编&#xff08;生成机器可识别代码&#xff09; 2.4 链接&#xff08;生成可执行文件或库文件&#xff09; 3 函数库 3.1 分类 3.2 图解 4 gcc选项 1. 背景知…

开源工具系列2:Trivy

在云原生安全的场景中&#xff0c;一个常见的场景就是对漏洞和配置进行扫描&#xff0c;以发现整个 K8s 环境的安全问题。今天我们来介绍一个高效的扫描工具Trivy。 Trivy 是什么 Trivy&#xff08;tri 发音为 trigger&#xff0c;vy 发音为 envy&#xff09;是一个简单而全面…

QT 学习笔记(十七)

文章目录一、多线程简介1. 基础知识2. 多线程的优缺点及注意事项二、多线程详解1. 背景案例2. 通过多线程对背景案例进行优化3. 方法一&#xff1a;多线程的创建使用&#xff08;QT 4.7 以前&#xff09;3.1 方法一的创建步骤3.2 方法一的具体实现及实现代码4. 方法二&#xff…

Android Hook之Frida安装使用

目录Frida安装安装frida-serverfrida-server配置和启动Frida Hook实例1&#xff1a;实例2&#xff1a;Frida 常用命令Frida 是一个动态检测框架&#xff0c;允许开发人员在 Windows、macOS、Linux、iOS 和 Android 上的原生应用程序中注入 JavaScript 或 Python 脚本。该框架可…

Spring复习(二)

FactoryBean FactoryBean是一个接口&#xff0c;需要创建一个类实现该接口 package com.mao.pojo;import org.springframework.beans.factory.FactoryBean;public class StudentFactoryBean implements FactoryBean {//getObject方法将对象交给Spring容器来管理Overridepubli…

Go web开发

使用 Gin-Plus 框架快速进行 web 开发 一、前言 安装 Get go get github.com/archine/gin-plus/v2v2.0.0Mod # go.mod文件加入下面的一条 github.com/archine/gin-plus/v2 v2.0.0# 命令行在该项目目录下执行 go mod tidy二、项目使用 1、启动入口 定义 main 文件&#xf…

来自一位双非本科大二学生的?自我救赎:堕落——蜕变

回望2022&#xff1a;获得&#xff1f;&#xff1a;失去&#xff1b;开心&#xff1f;&#xff1a;难过&#xff1b;伤心&#xff1f;&#xff1a;释怀 先提一句&#xff0c;总结2022&#xff0c;有后悔、不甘&#xff1b;有开心、感动&#xff1b;2022结束&#xff0c;更多的是…

springboot 2.6.6读不到nacos上的配置文件

搭建了一个微服务项目 spring boot 版本&#xff1a;2.6.6 spring cloud 版本&#xff1a;2021.0.1 spring cloud alibaba 版本&#xff1a;2021.0.1.0 遇到的问题无论是在application.yml还是在bootstrap.properties属性文件里配置服务中心相关的的信息都不能读取nacos上的…