C++自动推导与函数模板

news2024/12/25 1:01:51

自动推导、函数模板、类模板

目录

  • 1. 自动推导出数据类型
  • 2. 函数模板
    • 基本概念
    • 注意事项
    • 函数模板的具体化
    • 函数模板分文件编写
    • 函数模板高级
    • 函数后置返回类型

1. 自动推导出数据类型

auto关键字

linux 系统下使用的话,要在编译时 —std==c++11

注意:

  1. auto声明的变量必须在定义时初始化
  2. 初始化的右值可以是具体的数值,也可以是表达式和函数的返回值等
  3. auto不能作为函数的形参类型
  4. auto不能直接声明数组
  5. auto不能定义类的非静态成员

不要滥用auto,auto在编程时真正的用途如下

  1. 代替冗长复杂的变量声明:例如函数指针
  2. 模板中,用于声明依赖模板参数的变量
  3. 函数模板依赖模板参数的返回值
  4. 用于lambda表达式

2. 函数模板

基本概念

注意:库函数中有swap()函数,声明函数不要重名,可以首字母大写

虽然我们可以重载多个交换函数,来满足交换不同数据类型的要求,但是这种交换的方式好像不是很高明,需要很多重复代码,而且如果有新的自定义的数据类型,还需要新的交换函数

函数模板是通用的函数描述,使用任意类型(泛型)来描述函数

编译的时候,编译器推导实参的数据类型,根据实参的数据类型和函数模板,生成该类型的函数定义

生成函数定义的过程称为实例化

在这里插入图片描述

函数模板实例化

在这里插入图片描述

函数模板在实例化的过程中,编译器会在函数名中加入一些乱七八糟的东西,再用编译后的函数名替换代码中对应的函数调用。

如果不想编译器自动类型推导,可以再函数名后面加参数类型

Swap<String>(a, b);

注意事项

  1. 可以为类的成员函数创建模板,但不能是虚函数和析构函数

  2. 使用函数模板时,必须明确数据类型,确保实参与函数模板能匹配得上

    都是T类型的形参,传入的实参类型应该相同

    下面这里如果在调用函数的时候不明确数据类型的话就会报错
    在这里插入图片描述

  3. 使用函数模板时,推导的数据类型必须适应函数模板中的代码

    意思是,函数模板可以推导任意数据类型,但是函数中的代码不一定适应数据类型

    例如:我们传入函数模板中一个自定义类型,但并没有重载+操作符,而在函数模板代码中又使用了相应的+操作,编译器就会报错

  4. 使用函数模板时,如果是自动类型推导,不会发生隐式类型转换,如果显示指定了函数模板的数据类型,可以隐式类型转换

    如果传入参数的类型与显式定义的类型不同,可以隐式类型转换成显式定义的类型

  5. 函数模板支持多个通用数据类型的参数

    模板函数可以有多个通用参数

  6. 函数模板支持重载,并且可以有非通用类型的参数

函数模板的具体化

可以提供一个具体化的函数定义,当编译器找到与函数调用匹配的具体化定义时,将使用该定义,不再寻找模板

就是函数模板通用化之外的一个具体化版本

有具体化定义的时候,会优先使用具体化定义

声明和定义可以分开写

语法

// template<> void 函数模板名<Gril>(参数列表)
template<> void 函数模板名(参数列表) {
  // 函数体
}

使用顺序

普通函数、函数模板、具体化的函数模板以及它们的重载版本

规则

  1. 具体化函数先于常规模板,普通函数优先于具体化和常规模板
  2. 如果希望使用函数模板,可以用空模板参数强制使用函数模板
  3. 如果函数模板能产生更好的匹配,将优先于非模板函数

函数模板分文件编写

函数模板一般放在头文件中

如果有函数模板具体化的情况,则不同

函数模板只是函数的描述,没有实体,创建函数模板的代码放在头文件中

函数模板的具体化有实体,编译的原理和普通函数一样,所以,声明放在头文件中,定义放在源文件中

函数模板高级

decltype 关键字

在这里插入图片描述

auto关键字可以一定程度上解决上面提到的tmp的类型无法确定的问题,但如果我们需要返回tmp的话,又该怎么办?

在C++11中,**decltype**关键字用于查询表达式的数据类型

语法:decltype(expression) var;

decltype分析表达式并得到它的类型,不会计算执行表达式函数调用也是一种表达式,因此不必担心在使用decltype的时候执行了函数。

推导规则

  1. 如果expression是没有用括号括起来的标识符,则var的类型与该标识符相同,包括const等限定符
  2. 如果expression是函数调用,则var的类型与函数的返回值相同(函数不能返回void,但是可以返回void * )
  3. 如果expression是左值(能取地址)(要排除第一种情况)、或者用括号括起来的标识符,则var的类型是expression的引用
    decltype(func()) da;
    decltype(func) fa;
    decltype((func)) da = func;
    
    decltype(a) da;
    // 下面中da是引用类型,需要进行初始化
    decltype((a)) da = a;
    
  4. 如果上面的条件都不满足,则var的类型与expression的类型相同

在实际应用的时候,只要记住**decltype**可以用来推导表达式的类型,返回的是表达式类型或者表达式类型的引用即可,如果报错了就多试几次

decltypeauto都可以用来类型推导,但是两者是不同的

  1. 用auto推导的时候需要初始化,decltype不需要
  2. 下面的例子中,auto会执行函数或者表达式,decltype不会
    decltype(func()) da;
    auto dd = func();
    

左值和右值的区别

函数后置返回类型

在C++11标准中,下面的两种形式是等价的

int func(int x, double y);
// 等同于
auto func(int x, double y) -> int;

这里的auto是一个占位符,C++11中给auto新增的角色,为函数返回值占了一个位置

在这里插入图片描述

C++14标准中,auto可以直接推导函数的返回类型,不需要再使用decltype

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

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

相关文章

关于B+树的介绍、用途和c++代码实现

数据结构和算法的重要性不言而喻&#xff0c;一些优秀的开源项目的核心和灵魂就是数据结构、算法。在实际的编程中我们经常可以在各种框架、算法中看见B树、B树的身影。特别是在数据库的数据库引擎中&#xff0c;它们更是占据着重要的地位。 下面我将通过简单的二叉树&#xff…

2023/5/12总结

这俩天主要花时间在项目上&#xff1a; 实现了创建群聊和添加群聊&#xff1a; 点击创建群聊&#xff1a; &#xff0c;点击确定之后&#xff0c;会分配到一个群聊&#xff0c;默认头像会是下面这个圆形的头像&#xff1a; 添加群聊&#xff1a; 如果你要加入的群聊在自己的列…

06-HTML-列表标签

1、 <ul> 标签定义无序列表。 2、<ol> 标签定义有序列表。 属性值描述compactcompact HTML5 中不支持。HTML 4.01 中不赞成使用。 规定列表呈现的效果比正常情况更小巧。 reversedreversed规定列表顺序为降序。(9,8,7...)startnumber规定有序列表的起始值。type 1A…

为什么使用ConcurrentHashMap

currentHashMap的介绍 ConcurrentHashMap是线程安全并且高效的一种容器,我们就需要研究一下ConcurrentHashMap为什么既能够保证线程安全,又可以保证高效的操作。 为什么使用ConcurrentHashMap,我们就需要和HashMap以及HashTable进行比较&#xff1f; HashMap是线程不安全的&…

唐朔飞计组 第六章运算方法简单复习

在计算机中参与运算的数有两类&#xff1a;有符号数和无符号数 int 和unsigned unsigned可以看成是正数或者绝对值。 有符号数分为原码反码和补码 原码和反码的表示范围是相同的 但是补码由于将-0的位置换成2^n所以补码表示范围比原码和反码要多一位&#xff0c; 判断溢出比较…

诚邀社区开发者参与DeepBook测试和集成

DeepBook是Sui的基础流动性层&#xff0c;Sui基金会诚挚邀请社区开发者参与其测试和集成。 DeepBook为Sui的原生中央订单簿&#xff08;Central Limit Order Book&#xff0c;CLOB&#xff09;和基础流动性层&#xff0c;将会在未来数周准备完成&#xff0c;我们邀请大家参与测…

Unity大面积草地渲染——4、对大面积草地进行区域剔除和显示等级设置

目录 1、Shader控制一棵草的渲染 2、草地的动态交互 3、使用GPUInstancing渲染大面积的草 4、对大面积草地进行区域剔除和显示等级设置 Unity使用GPU Instancing制作大面积草地效果 大家好&#xff0c;我是阿赵。 这里开始讲大面积草地渲染的第四个部分&#xff0c;对大面积草地…

零知识证明:安全定义

之前在本科的课程仅仅略微介绍了下零知识证明&#xff0c;之后自学了一些相关内容&#xff0c;但不成体系。本学期跟着邓老师较为系统地学习了 ZKP&#xff0c;发现自己之前有很多的误解&#xff0c;临近期末整理下重要内容。 参考文献&#xff1a; Goldreich O. Foundations…

C语言实现个人通讯录(功能优化)

实战项目---通讯录&#xff08;功能优化&#xff09; 1.基本思路介绍&#xff1a;1.1基本思路&#xff1a; 2.通讯录的具体实现&#xff1a;2.1 通讯录的建立&#xff1a;2.2通讯录功能&#xff1a; 3.具体功能函数的实现&#xff1a;3.1 增添联系人&#xff1a;3.2 删除联系人…

从零开始学习JVM--初识Java虚拟机

1 虚拟机与Java虚拟机 1.1 基本介绍 所谓虚拟机&#xff08;Virtual Machine&#xff09;。就是一台虚拟的计算机。它是一款软件&#xff0c;用来执行一系列虚拟计算机指令。大体上&#xff0c;虚拟机可以分为系统虚拟机和程序虚拟机。 系统虚拟机&#xff1a;完全对物理计算…

树莓派(主)与STM32(从)使用SPI通信(持续更新中)

1.实验目的 使用树莓派作为主机向 STM32 从机发送数据&#xff0c;STM32 收到数据后通过串口的方式将数据打印到电脑上&#xff0c;同时返回给树莓派数据。树莓派接收到数据后打印在控制台上。 2.SPI 简介 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接…

进程控制下(程序替换部分)

目录&#xff1a; 1. 进程程序替换的原理 2.将磁盘的数据和代码加载进物理内存 3.程序替换函数的基本使用 ----------------------------------------------------------------------------------------------------------------------------- 1. 进程程序替换的原理 蓝色框内…

图解LeetCode——48. 旋转图像

一、题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 二、示例 2.1> 示例 1&#xff1a; 【输入】matrix [[1,2,3],[…

AVL树的实现

文章目录 AVL树前言1. AVL树的概念2. AVL树的结构2.1 AVL树节点的定义2.2 AVL树的结构 3. AVL树的操作3.1 AVL树的插入3.2 AVL树的旋转(重要)3.2.1 左单旋过程代码 3.2.2 右单旋过程代码 3.2.3 左右双旋过程代码 3.2.4 右左双旋过程代码 旋转整体代码 3.3 AVL树的验证3.4 AVL树…

Day967.团队拓扑学 -遗留系统现代化实战

团队拓扑学 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于团队拓扑学的内容。 看看最近这几年来新诞生的组织结构模型——团队拓扑学&#xff08;Team Topologies&#xff09;。 一、团队拓扑 尽管组件团队、特性团队和 Spotify 模型&#xff0c;都为团队的组成提…

JavaScript实现输入年份判断是否为闰年的代码

以下为实现输入年份判断是否为闰年的程序代码和运行截图 目录 前言 一、输入年份判断是否为闰年 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择&#xff0c;您可以在目录里进行快速查找&#xff1b; 2.本博文代码可以根据题目要…

阿里云 aliplayer 加密的视频 key解密解密下载过程实现

第一步&#xff1a;打开开发者工具 打开需要下载的视频链接&#xff0c;按F12打开开发者工具&#xff0c;然后强制刷新&#xff08;ctrlf5&#xff09; 第二步&#xff1a;定位key加密 内存搜索&#xff0c;关键词&#xff1a;_sce_dlgtqred 进入第二个结果&#xff1a;https…

Map在循环中修改自己的key与value

Map在循环中修改自己的key与value 1.解决方案2.深入了解 1.解决方案 使用ConcurrentHashMap package com.company.newtest;import java.util.*; import java.util.concurrent.ConcurrentHashMap;public class test30 {public static void main(String[] args) {Map<String…

【Linux】进程信号详解(一)信号概念信号产生

文章目录 前言信号概念信号入门1.查看所有信号2.信号处理常见方式3. 发送信号过程信号是谁发送的&#xff1f; 信号产生介绍signal函数来捕捉进程1.通过键盘产生例子&#xff1a;Core Dump核心转储 2.程序出现异常&#xff0c;导致收到信号空指针异常浮点数异常 3. 调用系统函数…

1_1torch基础知识

1、torch安装 pytorch cuda版本下载地址&#xff1a;https://download.pytorch.org/whl/torch_stable.html 其中先看官网安装torch需要的cuda版本&#xff0c;之后安装cuda版本&#xff0c;之后采用pip 下载对应的torch的gpu版本whl来进行安装。使用pip安装时如果是conda需要切…