【C++扩展】函数别名

引言

int f(int param) {return d(param);
}

上面这段代码看着是不是很不合理,为什么不直接调用d函数,而非要通过f函数来调用d函数?

正文

意义

引言部分抛出的问题如何解答?
其实,抛开代码的语义和业务功能,单从语法层面来说,这种写法没有问题,但不合理。
但是,我们实际开发场景中最重要的就是要实现业务功能,在这个基础上来优化代码的语义。

语义清晰性

在实际的程序中,因为封装的层级不同,函数的命名会有很大的区别,比如:
底层模块提供了一个接口是calculateHashSum,用来计算哈希值;
但是在业务层需要通过calculateHashSum来实现验证数据的功能,那么我们在业务层调用时往往会封装一个名为validateData的接口,在这个接口中调用calculateHashSum函数,代码如下:

bool validateData(string data) {return calculateHashSum(data);
}

从代码语义来看,业务层不关心底层是通过什么方式实现的验证功能,所以这种方式能够大大的提高代码语义的清晰性。
当然,这种方法也存在缺点:

  • 如果函数没有内联,它可能会创建额外的副本
  • 如果有多个参数需要传递给底层接口,那么就需要大量烦人的代码
  • 调试时,需要执行额外的步骤

C++11:函数别名

C++11提供了一种函数别名的方法来解决创建额外副本的副作用:

const auto validateData = calculateHashSum;

这种方式就是给函数取了一个别名,在实际调用时不是调用validateData函数,而是调用calculateHashSum函数。

注意:不能取消const!如果取消const会使validateData能够随时变更指向其他函数,容易产生异常。

原理

在C++中,const auto关键词被用来自动推断validateData的类型,并将其声明为一个常量。这意味着一旦validateData被赋值为 calculateHashSum后,它不能再被赋值为其他的函数或值。

calculateHashSum是一个函数,而在C++中,函数名本身可以被视为一个指向该函数的指针。当你写const auto validateData = calculateHashSum; 时,你实际上是创建了一个新的函数指针validateData,并让它指向calculateHashSum函数的地址。因此,validateData成为了calculateHashSum的一个别名,你可以通过validateData调用calculateHashSum函数。

底层实现

  1. 函数指针:在底层,函数别名是通过函数指针实现的。函数指针是一个变量,存储着一个函数的内存地址。当你将一个函数赋值给另一个变量时,你实际上是在复制该函数的内存地址到新变量中。这样,通过新变量调用函数时,它会跳转到这个地址执行代码。

  2. 内联替换:编译器可能会在某些情况下优化这种函数指针的使用。如果编译器能够确定通过别名调用的函数,并且这种调用非常频繁,它可能会选择内联这个函数的调用,这意味着函数调用会被替换为函数体本身的代码,以减少函数调用的开销。

  3. 类型安全:在C++中,使用auto关键字可以确保类型安全,因为编译器会自动推断正确的类型。这样可以避免由于类型不匹配导致的编译错误或运行时错误。

C++14:模板函数别名

如果我们想为模板函数添加别名要怎么办?

template<typename T>
void d(T) {}

添加别名:

template<typename T>
const auto f = d<T>;

注意:这是C++14加入的功能

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

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

相关文章

.哈希表.

哈希 哈希表&#xff1a;将大而复杂的数据映射到紧凑的区间内。分为&#xff1a;①存储结构 &#xff08;离散化是特殊的哈希&#xff0c;之前讲的离散化是严格保序的 映射到区间上是连续递增的&#xff09; 哈希不保序&#xff0c;这里讲的是一般的哈希 弊端&#xff1a;若…

Linux(四)

Linux&#xff08;四&#xff09; shell脚本shell脚本开发过程创建创建.sh文件编写.sh文件添加执行的权限 chmod 777 1.sh运行 shell中注释shell中变量用户自定义变量 (尽量大写)位置参数即命令行参数预定义变量环境变量 shell中程序和语句说明性语句功能性语句echo 输出read 键…

网上打印试卷的步骤是什么

对于学生和家长来说&#xff0c;打印试卷是日常学习中的一项重要需求。那么&#xff0c;如何在网上方便地打印试卷呢&#xff1f;下面&#xff0c;就让我来为您介绍琢贝云打印的试卷打印步骤。 一、选择琢贝云打印的原因 支持多种文件格式打印&#xff0c;包括图片、PPT、PDF、…

每日百万交易的支付系统,如何设置JVM堆内存大小?

每日百万交易的支付系统,如何设置JVM堆内存大小? 1、支付背景的引入2、支付的核心业务流程3、每日百万交易支付系统的压力在哪里?4、支付系统每秒钟需要处理多少笔支付单5、每个支付订单处理需要耗时多久6、每个支付订单大概需要多大的内存空间7、每秒发起的支付请求对内存的…

手撕C语言题典——消失的数字

目录 前言 一&#xff0c;思路 1)排序查找 2&#xff09;数据求和&#xff0c;依次减去中值 3&#xff09; 异或 二&#xff0c;异或的代码实现 前言 依旧是一道力扣上的题&#xff0c;通过不同思路的不同时间复杂度来分析&#xff0c;让我们看看有什么不同。 面试题 17…

贪心-ACW803区间合并-XMUOJ力量碎片合并

题目 思路 附上几个参考链接 for(auto i : v)遍历容器元素_for auto 遍历-CSDN博客 C pair的基本用法总结&#xff08;整理&#xff09;_c pair用法-CSDN博客 使用 sort 实现自定义排序 - AcWing 话不多说&#xff0c;直接上代码 代码 /* ACW803区间合并-XMUOJ力量碎片合…

sql server怎么存储图片

sql server怎么存储图片 在SQL Server中&#xff0c;可以使用VARBINARY数据类型来存储图片。以下是一个简单的例子&#xff0c;展示了如何将图片存储到数据库中&#xff0c;并从数据库中检索出来。 首先&#xff0c;创建一个表来存储图片数据&#xff1a; CREATE TABLE Image…

MySQL查询某个字段含有字母数字的值

在MySQL中&#xff0c;要查询某个字段含有字母和数字的值&#xff0c;可以使用正则表达式配合REGEXP操作符。以下是一个详细的示例&#xff0c;说明如何编写这样的查询。 假设我们有一个名为my_table的表&#xff0c;其中有一个名为my_column的字段&#xff0c;我们想要查询这…

第13章-循迹功能 循迹小车讲解 原理分析 STM32智能小车循迹教程 红外对管使用 PID循迹算法分析

讲解一下我们小车里面的循迹部分&#xff0c;包括红外基础使用&#xff0c;无PID循迹和有PID循迹。 第13章-循迹功能 13.1-非PID循迹功能完成 先红外对管调试 我们这里学习一下&#xff0c;如何实现循迹功能 如何才能让小车沿着黑线运动、要让小车感知到黑线的位置&#x…

正运动VPLC系列机器视觉运动控制一体机快速入门

VPLC系列机器视觉运动控制一体机快速入门&#xff08;一&#xff09;-正运动技术 (zmotion.com.cn) VPLC系列机器视觉运动控制一体机快速入门&#xff08;二&#xff09;-正运动技术 (zmotion.com.cn) VPLC系列机器视觉运动控制一体机快速入门&#xff08;三&#xff09;-正运…

C/C++ vector详解

要想了解STL&#xff0c;就必须会看&#xff1a; cplusplus.comhttps://legacy.cplusplus.com/ 官方内容全都是英文的&#xff0c;可以参考&#xff1a; C/C初始识https://blog.csdn.net/2301_77087344/article/details/138596294?spm1001.2014.3001.5501 vector&#xff…

sql聚合函数使用-笔记

sql聚合函数使用-笔记 SELECT SUM ( case when procurement_type 公益推送 then 1 else 0 end ) gywxTotal,SUM ( CASE WHEN (status 1 and procurement_type 公益推送) THEN 1 ELSE 0 END ) gywxYsc,SUM ( CASE WHEN (status ! 1 and procurement_type 公益推送) THEN 1 …

十二、OpenAI语音转文本

1 介绍 音频API提供两个语音转文本的端点&#xff0c;transciptions 和 translations, 它们基于最强的开源模型large-v2 Whisper.可以被使用到&#xff1a; 将音频转换成任何语言的音频翻译并转化音频到英文 上传文件的大小限制在25M以内&#xff0c;支持的音频格式有&#x…

【Typescript】类、类实例、构造函数、类是否也是构造函数....

务必注意&#xff1a;Typescript中类也是一个构造函数【可以new】但是有时候针对不确定的类型需要as转换一下 才能new class Test { }class Test01 extends Test {a 1 }function ok<T extends typeof Test>(asyncClass: T): T {/*** 1. 这里的T是一个【类的类型】*/ret…

Java面试题:请分析Java中的并发工具类,如ConcurrentHashMap和CopyOnWriteArrayList的内部实现原理

Java中的并发工具类是java.util.concurrent包提供的一些用于多线程环境下的集合类&#xff0c;它们通过不同的机制来保证线程安全。以下是ConcurrentHashMap和CopyOnWriteArrayList的内部实现原理分析&#xff1a; ConcurrentHashMap ConcurrentHashMap是一个线程安全的哈希表…

React常见面试题及参考答案(3万字长文)

目录 描述React中的组件生命周期 解释React中的JSX是什么 什么是React中的虚拟DOM?

辐射度技术在AI去衣中的魅力与科学

引言&#xff1a; 在当今的数字化时代&#xff0c;人工智能正逐渐渗透到我们生活的方方面面。其中&#xff0c;AI去衣技术作为一项颇具争议但又不失其科技创新的应用&#xff0c;正引起越来越多的关注和讨论。而在实现高质量图像渲染的过程中&#xff0c;辐射度技术凭借其卓越的…

CAD二次开发(5)-用户交互仿系统命令

1. 工具类&#xff1a;PromptTool.cs using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace _04用户交互 {public static…

封装 UpdateManager 实现启动微信小程序时自动强制更新

背景 微信小程序发布新版本后&#xff0c;微信有自己的更新策略&#xff1a;异步更新、同步更新。异步更新会在用户下次冷启动时才会加载新版本&#xff0c;本次打开的仍然是旧版本。为了保证更多用户能够访问的新版本&#xff0c;本文利用微信wx.getUpdateManager()暴露的Upd…