函数/类模板详解

目录

概述

函数模板

1.函数模板的定义

2.函数模板的使用

3.非类型的模板参数

类模板

1.函数模板的定义

2.类模板的成员函数

3.模板类名字的使用

4.非类型的模板参数


概述

泛型编程是一种编程思想,其追求摆脱数据类型的束缚,通过将数据类型作为参数的处理,提高代码的通用性。模板是泛型编程的基础,它支持将数据类型作为参数,从而使得我们在处理具有相似性的对不同数据类型的处理时大大减少类代码量。模板在定义时并不会占有内存,而是在我们使用模板时针对我们的参数具体产生一个处理此类参数的函数/类,并在此时分配内存,这个过程就叫做模板的实例化。

模板大致可以分为函数模板和类模板。两者有很多相似之处,但也略有不同。

函数模板

1.函数模板的定义

下面提供简单的函数模板定义代码:

template<class T>//此处class并不是定义类,而是标注T代表一个类型名。
//class也可以用typename替代,作用相同
void CoutInformation(T a)//此处为函数CoutInformation的形参列表。
{
cout<<a<<endl;
}CoutInformation<int>(5);//显式
char a("666");
CoutInformation(a);//隐式

定义模板使用template关键字,与相连的<>内的是模板参数列表,可以在此处列出需要的类型,多个类型要使用多个class或者typename并用逗号隔开,但不建议class和typename混用。class和typename 可以标志T为类型参数,这里T也是自主起的来代替类型的名称,可以自主选择。编译器允许定义模板函数同名的函数,如果条件相同,编译器会优先调用非模板函数,且不会在生成此模板函数的实例化版本。

一般我们将把函数模板的定义放在.h文件中,在用include将其包含到.cpp文件中。(不需要考虑函数模板的重定义问题。)

模板函数可以写成内联函数,inline声明写于<>与函数返回类型之间。

2.函数模板的使用

当我们调用模板函数时我们可以使用尖括号明确表示我们的参数类型,也可以省略尖括号让编译器自主帮我们推断参数类型。函数参数都有了明确的类型,编译器就会实例化出针对此类型的实例化版本,当我们再次调用相同类型的参数时,编译器就会调用模板函数的实例化版本,不会再二次实例化。但我们省略模板参数列表时,我们要确保编译器可以通过我们传递的函数实参推断出模板参数列表中的内容。当我们使用<>明确模板参数的时候,要确保与函数实参的类型相匹配。

我们可以这样认为,模板函数的定义并不会让编译器生成代码,只有在我们调用函数模板时,编译器为我们实例化特定版本的函数之后,编译器才生成代码。也就是说,函数模板就像一张图纸一样,一旦我们有了图纸中的参数,我们就可以通过这些参数具体的将图纸中的内容建设出来。

3.非类型的模板参数

template<typename T,int a>//a为非类型模板参数
int CoutInformation(T b)
{
cout<<b<<endl;
return a;
}int c=520;
int d=CoutInformation<int,100>(a);

模板参数不仅仅是类型参数,也可以是非类型参数,也就是一段数据。对于非类型参数,我们需要用具体的数据类型来修饰。这些非类型模板参数同样可以被编译器推断,如果编译器无法推断出这些非类型模板参数的值,就需要我们使用<>具体的给它提供值。同时,需要注意的是模板实例化发生在编译的过程。因此我们使用<>提供的模板参数都应该为常量表达式,否则编译器将会报错。

下面提供特殊示例:

#include<iostream>
using namespace std;
template<unsigned L1,unsigned L2>
void Coutchar(const char a[L1],const b[L2])
{
cout<<a<<"and"<<b<<endl;
}
int main()
{
Coutchar("yes","no");//此时非类型模板参数L1,L2就是编译器推断的//但是如果我们使用<5,4>提供非类型模板参数,编译反而会报错,//因为系统推断"yes"长度为4,"no"长度为3,传递参数与系统推断不符
}

类模板

1.函数模板的定义

template<typename T>
class Goodclassname 
{
public :void CoutInformation(){cout<<a<<endl;}
private :T a;
};

和函数模板相似,我们也可以通过类模板的实例化功能来避免代码的重复性。但需要注意的是,类模板并不能像函数模板那样推断模板参数的内容,也就是说,我们必须使用<>来明确类模板参数的内容。同时,类模板也可以在模板参数列表中设定默认参数值。

2.类模板的成员函数

如果我们将类模板的成员函数的函数体写在类模板定义的内部,和普通类成员函数一样,其也会被隐式声明为内联函数。如果我们将类模板的成员函数的函数体写在类模板定义的外部,那我们就需要标明类模板的模板参数,也就是在函数前使用template<>,同时在尖括号内将所有模板参数名列出,多个模板参数之间用逗号分隔。这是因为类模板一旦被实例化之后就会产生自己版本的成员函数,也就是说,类模板的成员函数拥有与类模板相同的模板参数。

一个类模板可以有多个成员函数。当类模板被实例化时,并不是说全部的成员函数都将被实例化。而是实例化那些被使用过的成员函数。也就是说,一个类模板的成员函数只有在使用的时候才被实例化。

template<class T>
class Goodclassname
{
public:void CoutInformation();
private:T a;
};template<class T>
void Goodclassname<T>::CoutInformation()
{cout<<a<<endl;
}

3.模板类名字的使用

在类模板定义内部我们直接使用类模板的名字并不需要带上类模板参数,因为系统默认模板类内的成员的模板参数与模板类保持一致。但是我们在类模板定义外面使用类模板名称的时候,应在类模板名字后使用<>列出模板参数,因为这样才能表示的是一个已经被实例化的类模板。

当非模板类子类继承模板类父类时,应该明确父类中模板参数的类型,这样才可以确定子类的内存。否则子类也应定义为模板类,再用子类的模板参数给父类模板参数中确定模板类型,这样可以提高父类的灵活性。

template<class T>
class Fathername//父类
{
public:
T a;
};
template<class R,class P>
class Sonname :public Fathermame<R>//子类
{
public:
P b;
};

4.非类型的模板参数

类模板参数同样不局限与类型,也可以拥有非类型的模板参数。但是需要注意的是,浮点型,类型型不能当做非类型模板参数传递。

template<class T,int a=1;>
class Goodclassname
{
public:int CoutInformation();
private:T a;
};template<class T,int a>
int Goodclassname<T,a>::CoutInformation()
{cout<<a<<endl;return a;
}

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

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

相关文章

Redis数据库:高可用(主从复制、哨兵模式、cluster集群)

目录 前言 一、Redis数据库高可用 二、Redis 主从复制 1、Redis主从复制概述 1.1 Redis主从复制概念 1.2 Redis主从复制的作用 1.3 Redis主从复制的流程 2、搭建Redis主从复制 2.1 环境部署 2.2 主服务器修改配置文件 2.3 从服务器修改配置文件 2.4 测试主从复制效…

负氧离子监测站解析

TH-FZ4防腐木负氧离子监测站&#xff0c;作为一种独特的空气质量监测设备&#xff0c;以其独特的优势在生态环保领域发挥着日益重要的作用。这种监测站不仅具备防腐木材质带来的天然美感与耐久性&#xff0c;更结合了先进的负氧离子监测技术&#xff0c;为环境保护和生态旅游等…

[开源]基于SVM的时间序列预测python代码

整理了SVM的时间序列预测python代码分享给大家。记得点赞哦 #!/usr/bin/env python # coding: utf-8import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn import preprocessing from sklearn.metrics import mean_squared_error from math i…

短剧小程序系统开发,让短剧观看与创作更加便捷。短剧系统源码搭建

一、目前短剧发展趋势 1. 市场规模&#xff1a;根据数据来看&#xff0c;2023年中国微短剧市场规模达到了373.9亿元&#xff0c;同比上升了267.65%。预计2024年市场规模将超过500亿元。这一市场规模的增长速度非常显著&#xff0c;显示出短剧行业的巨大潜力和发展前景。 2. 投…

蓝桥杯考前复习三

1.约数个数 由乘法原理可以得出&#xff1a; import java.util.*; public class Main{static int mod (int)1e9 7;public static void main(String[] args){Map<Integer,Integer> map new HashMap<>(); //创建一个哈希表Scanner scan new Scanner(System.in);i…

【会议】Oracle自动化运维峰会

2023年7月21日&#xff0c;杭州。我组织了Oracle自动化运维峰会&#xff0c;大约有20人左右参加会议。以下是会议主题&#xff1a; Oracle自动化运维能力是Oracle 19c自动化运维体系中非常重要的一环&#xff0c;自动化索引、自动化SQL优化、资源隔离等技术能够非常好的提升运维…

Java基于微信小程序的校园外卖平台系统,附源码

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

定制您的设备体验:如何更改Android启动动画

“bootanim"通常是指在操作系统启动过程中显示的动画&#xff0c;尤其是在移动设备或某些定制的Linux发行版中较为常见。这个术语并不是一个标准的命令或工具名称&#xff0c;而是通常用来描述"启动动画”(boot animation)的简称。在Android设备中&#xff0c;启动动…

UVA1395 Slim Span 解题报告

UVA1395 Slim Span 解题报告 题目链接 https://vjudge.net/problem/UVA-1395 题目大意 给出一个n&#xff08;n≤100&#xff09;结点的图&#xff0c;求苗条度&#xff08;最大边减最小边的值&#xff09;尽量小的生成树。 解题思路 将边按照权值从小到大排序之后&#x…

【云开发笔记NO.24】中间件和中台

在云开发领域&#xff0c;中间件是一个至关重要的概念&#xff0c;它扮演着连接不同技术组件和应用程序的桥梁角色。中间件&#xff0c;顾名思义&#xff0c;是处于两个应用程序或系统之间的软件层&#xff0c;其主要负责屏蔽底层操作系统的复杂性&#xff0c;为上层应用程序提…

学习java第三十六天

Spring 官网列出的 Spring 的 6 个特征: 核心技术 &#xff1a;依赖注入(DI)&#xff0c;AOP&#xff0c;事件(events)&#xff0c;资源&#xff0c;i18n&#xff0c;验证&#xff0c;数据绑定&#xff0c;类型转换&#xff0c;SpEL。 测试 &#xff1a;模拟对象&#xff0c;…

题目 2016: 新生的入队仪式

题目描述: 有一名新生加入了合唱队&#xff0c;我们给他举办了一个非常大的欢迎仪式。欢迎过后&#xff0c;同学们想要给他安排一个合唱时&#xff0c;他需要站的位置。而合唱队是两面低&#xff0c;中间高的。这个同学可能会站在左面或者右面&#xff0c;或者&#xff0c;他作…

C++ vector顺序表模拟实现

目录 前言&#xff1a; 模拟实现&#xff1a; 构造函数&#xff1a; 析构函数&#xff1a; 容量调整&#xff08;reserve&#xff09;&#xff1a; resize函数&#xff1a; 尾插&#xff08;push_back&#xff09;: 尾删&#xff08;pop_back&#xff09;: 插入&#xff…

C++ | Leetcode C++题解之第8题字符串转换整数atoi

题目&#xff1a; 题解&#xff1a; class Automaton {string state "start";unordered_map<string, vector<string>> table {{"start", {"start", "signed", "in_number", "end"}},{"signed…

如何判断超级充电测试的性能

超级充电测试是电动汽车充电设备性能评估的重要环节&#xff0c;其性能的好坏直接影响到电动汽车的充电效率和使用寿命。以下是判断超级充电测试性能的几个关键因素&#xff1a;这是衡量超级充电测试性能的最直接指标&#xff0c;充电速度快意味着电动汽车可以在更短的时间内完…

商业分析思维与实践:用数据分析解决商业问题

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

日期时间相关的类

分界线jdk8 jdk8之前和之后分别提供了一些日期和时间的类&#xff0c;推荐使用jdk8之后的日期和时间类 Date类型 这是一个jdk8之前的类型&#xff0c;其中有很多方法已经过时了&#xff0c;选取了一些没有过时的API //jdk1.8之前的日期 Date Date date new Date(); // 从1970年…

区块链的网络架构有哪些?

区块链技术的兴起正在深刻地改变着互联网的格局。它不仅提供了去中心化、数据透明、难以篡改等优势&#xff0c;还为各种应用场景提供了新的可能性。为了更好地理解区块链&#xff0c;我们需要深入探讨其网络架构。 区块链网络架构主要由以下几个部分组成&#xff1a; 1. 区块…

Web 前端性能优化之五:构建优化

4、构建优化 资源的合并与压缩所涉及的优化点包括两方面&#xff1a;一方面是减少HTTP的请求数量&#xff0c;另一方面是减少HTTP请求资源的大小。 1、HTML 压缩 1、什么是 HTML 压缩 百度首页部分 HTML 源代码 谷歌首页部分 HTML 源代码 虽然这些格式化的字符能带来很好的代…

SpringBoot及其特性

0.前言 Spring 框架提供了很多现成的功能。那么什么是 Spring Boot&#xff1f;使用 Spring 框架&#xff0c;我们可以避免编写基础框架并快速开发应用程序。为了让 Spring 框架提供基础框架&#xff0c;我们需要向 Spring 框架描述有关我们的应用程序及其组件的信息。 不只是…