【学习记录】PointLIO代码 update_iterated_dyn_share_modified 中函数指针的用法

最近在看PointLio的代码,有一部分看了半天没看懂,学习整理如下。

1、PointLio在迭代卡尔曼部分的代码

esekfom.hpp中,有部分代码如下:

void init_dyn_share_modified(processModel f_in, processMatrix1 f_x_in, measurementModel_dyn_share_modified h_dyn_share_in)
{f = f_in;f_x = f_x_in;// f_w = f_w_in;h_dyn_share_modified_1 = h_dyn_share_in;maximum_iter = 1;x_.build_S2_state();x_.build_SO3_state();x_.build_vect_state();x_.build_SEN_state();
}

之后,在迭代更新时,部分代码如下:

bool update_iterated_dyn_share_modified() {dyn_share_modified<scalar_type> dyn_share;state x_propagated = x_;int dof_Measurement;double m_noise;for(int i=0; i<maximum_iter; i++){dyn_share.valid = true;// 调用了 h_dyn_share_modified_1 函数,这个函数的类型是 `measurementModel_dyn_share_modified`// measurementModel_dyn_share_modified 是 void (state &, dyn_share_modified<scalar_type> &) 这个类型函数的一个别名;// 具体的,这个函数的实现是: h_dyn_share_modified_1 指向的 `h_dyn_share_in`(在初始化init_dyn_share_modified(_2h)中)// 而 h_dyn_share_in 是 h_model_input,在 estimateor.cpp 中被定义了具体实现。h_dyn_share_modified_1(x_, dyn_share);if(! dyn_share.valid){return false;// continue;}// 省略后续代码...

比较费解的是,上述代码中,h_dyn_share_modified_1(x_, dyn_share);这一行到底是在做什么。
仔细去看定义,可以发现,具体定义如下:

typedef Eigen::Matrix<scalar_type, m, n> processMatrix1(state &, const input &);
typedef Eigen::Matrix<scalar_type, m, process_noise_dof> processMatrix2(state &, const input &);
typedef Eigen::Matrix<scalar_type, process_noise_dof, process_noise_dof> processnoisecovariance;
typedef void measurementModel_dyn_share_modified(state &, dyn_share_modified<scalar_type> &);

其实也看不懂,于是问了下GPT,知道了这是“函数指针”,但还是云里雾里;又翻开了《C++Primer》和查阅了一些网络资料。

2、函数指针

函数指针和指针函数,区别如下:
在这里插入图片描述
图片来自哔哩哔哩:指针函数与函数指针

概括来说,函数指针,是一个指针,指向一个函数。那么面临着一个问题,这个函数到底是什么类型?

2.1 函数的类型

之前一直没有关注过函数的“类型”,《C++ Primer》指出:
在这里插入图片描述
即函数应该是一个 bool (const string&, const string&) 类型,那么函数指针就是一个指向这种类型的函数的一个指针。函数名称可以是任何名字。

2.2 形参为指针的函数

由于函数指针,本质上是一个指针,那么这个指针,可以当作另一个函数的形参,如下:
在这里插入图片描述
此时,useBigger这个函数接收的第3个参数是一个指针,这个指针指向了一个函数而已。

但是这种写法比较复杂,因此引入typedef关键字:

2.3 typedef 关键字

这里需要提一下typedef关键字。typedef是类型定义的替换,有一个视频讲的很好:
https://www.bilibili.com/video/BV15h4y1M7p2

在这里插入图片描述
即“用变量名替换上面typedef后面的类型,然后去掉typedef,剩下的就是这一行的定义”。

所以,再结合上面形参是指针的函数,可以写作这样:
在这里插入图片描述
我们把Func换成上方绿色的typedef定义,就能看懂了。

3、回到代码

下面回到PointLio中的代码,我们捋一下思路:

init_dyn_share_modified函数:

在初始化时,将h_dyn_share_modified_1这个“函数指针”和传入的形参h_dyn_share_in共享,即指向的都是h_dyn_share_in这个形参所代表的函数。

init_dyn_share_modified这个函数的调用,是在laserMapping.cpp中:

kf_input.init_dyn_share_modified(get_f_input, df_dx_input, h_model_input);

即传入的参数是指向h_model_input的指针,而这个h_model_inputEstimator.cpp中定义,就是“IMU做输入量的观测模型”(这里不展开解释,IMU的“输入”/“输出”的区别)。

update_iterated_dyn_share_modified函数:

那么,再往下,初始化完成以后,h_dyn_share_modified_1就指向了h_model_input这个函数,
在接下来update_iterated_dyn_share_modified函数中,h_dyn_share_modified_1(x_, dyn_share)就是相当于调用了h_model_input这个函数。

可以再去看h_model_input这个函数,和h_dyn_share_modified_1函数,传入的形参形式是一致的。所以,我理解的应该是正确的吧。

至此,搞明白了这部分的调用。

小彩蛋

当在代码中自己添加注释,解释这部分函数指针时,我想说“写的真复杂”,结果github的copilot自动补全了我的注释,如下:
在这里插入图片描述看样子可能不止我一个人被这个函数指针的写法绕进去过吧。

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

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

相关文章

上班族真香副业:工资4500,靠steam游戏搬砖项目月入过w

steam游戏搬砖项目已经存在好多年了&#xff0c;这个项目比较冷门且能持续稳定盈利&#xff0c;是一个非常不错的项目。即使你没玩过steam游戏也没关系&#xff0c;这个steam游戏搬砖项目既不需要你会玩游戏&#xff0c;也不需要你懂英语。 steam游戏搬砖项目的盈利点在汇率差和…

Python的数据库编程基础知识

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;如果停止&#xff0c;就是低谷&#xf…

【代码随想录算法训练营Day29】 491.递增子序列;46.全排列;47.全排列 II

文章目录 ❇️Day 29 第七章 回溯算法 part05✴️今日内容❇️491.递增子序列自己的思路随想录思路自己的代码 ❇️46.全排列思路代码流程 ❇️47.全排列 II思路代码 ❇️Day 29 第七章 回溯算法 part05 ✴️今日内容 491.递增子序列46.全排列47.全排列 II ❇️491.递增子序…

【性能测试】Jmeter+InfluxDB+Grafana 搭建性能监控平台

一、背景 为什么要搭建性能监控平台&#xff1f; 在用 Jmeter 获取性能测试结果的时候&#xff0c;Jmeter自带的测试报告如下&#xff1a; 这个报告有几个很明显的缺点&#xff1a; 只能自己看&#xff0c;无法实时共享&#xff1b;报告信息的展示比较简陋单一&#xff0c;不…

在外包公司搞了2年,出来技术都没了...

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了2年的的功能…

网络工程师笔记9

动态路由 RIP路由协议 配置简单 易于维护 适用于小型网络 周期性是30s发一次

MyBatis-Plus如何娴熟运用乐观锁

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 MyBatis-Plus如何娴熟运用乐观锁 前言乐观锁的基本概念基本概念和原理&#xff1a;为何乐观锁是解决并发问题的有效手段&#xff1a; MyBatis-Plus中乐观锁的支持1. Version 注解&#xff1a;2. 配置乐…

严刑拷打_微服务

文章详情 &#xff1a;&#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a; 微服务相关知识 ⏱️ 创作时间&#xff1a;2024年03月8日 ———————————————— 文章目…

高级语言讲义2014计专(仅高级语言部分)

1. 已知&#xff0c;连续函数在区间[0, 3]有且只有一个实根&#xff0c;编写完整程序&#xff0c;利用二分法计算并输出该实根的近似值&#xff0c;要求结果精确到。 二分法的基本思路是:对于区间[a, b]上的连续函数f(x)&#xff0c;若f(a)和f(b)的正负号不同&#xff0c;则该区…

unicloud where 使用

where介绍 在uniCloud中&#xff0c;WHERE是一个用于指定查询条件的关键字。它允许用户根据特定的条件来筛选和查询云数据库中的数据。WHERE语句的基本语法格式是WHERE condition&#xff0c;其中condition表示查询条件&#xff0c;可以是一个或多个逻辑表达式组成的条件。 在…

达梦数据库将DMHR模式下的表(迁移)导出为EXCEL文件

数据库迁移工具&#xff08;Data Transfer Service&#xff09;位于/dm8/tool/dts.其中/dm8是数据库安装目录。 在创建数据库时我们如果勾选了 “创建示例库DMHR(R)”&#xff0c;数据库实例中就带有这个数据库。 这里是用MobaXterm客户端远程控制ip地址为192.168.148.130的虚…

【C++】C++11---右值引用和移动语义

目录 1、什么是左值引用和右值引用2、左值引用与右值引用比较3、右值引用使用场景和意义4、右值引用引用左值的分析5、完美转发 1、什么是左值引用和右值引用 传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#xff0c;所以从现在开始我们之前学习…

Xilinx 7系列 FPGA硬件知识系列(九)——FPGA的配置

目录 1 .1配置模式 1.1.1 主模式 1.1.2 从模式 1.2 7种配置模式 1.2.1 主串配置模式 1.2.2 从串配置模式 ​编辑1.2.3 主并配置模式 1.2.4 从并配置模式 1.2.5 JTAG配置模式 ​编辑1.2.6 主SPI配置模式 ​编辑1.2.7 主BPI配置模式 1.2.8 FPGA BPI加载时间…

详解float函数类型转换

函数描述 float([x]) 函数将数字或数字的字符串表示形式转换为与它等效的有符号浮点数。如果参数x是一个字符串&#xff08;十进制表示的数字串&#xff09;&#xff0c;数字前面可以添加符号来表示正数&#xff0c;或负数。符号和数字之间不能出现空格&#xff0c;但是符号前…

【Linux基础(三)】信号

学习分享 1、信号的基本概念2、查看信号列表3、常见信号名称4、signal库函数5、发送信号kill6、kill - signal &#xff08;无参信号&#xff09;示例6.1、kill - signal (不可靠信号)示例6.2、kill - signal (可靠信号)示例 7、信号分类7.1、信号运行原理分类7.2、信号是否携带…

java-抢红包一些简单概念

抢红包&#xff0c;比如微信中抢红包&#xff0c;红包金额分配使用的是二倍均值算法。 二倍均值拆包&#xff1a; 拆包要求:所有人抢到的金额之和等于红包总额&#xff0c;每个人最少抢到 0.01 元&#xff0c;每个人抢到的红包金额不要相差太大二倍均值法:假设红包总金额是X&…

【Spring云原生系列】Spring RabbitMQ:异步处理机制的基础--消息队列 原理讲解+使用教程

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…

3DES算法的起源与演进:保障信息安全的重要里程碑

title: 3DES算法的起源与演进&#xff1a;保障信息安全的重要里程碑 date: 2024/3/8 21:25:19 updated: 2024/3/8 21:25:19 tags: 3DES算法起源安全性增强三次迭代加密密钥管理复杂效率对比AES应用场景广泛Python实现示例 一、3DES算法的起源与演进 3DES算法是DES算法的增强版…

Linux第72步_使用“新字符设备的一般模板”编写LED驱动

使用“新字符设备的一般模板”编写LED驱动&#xff0c;使用寄存器直接开关灯。 1、创建LED目录 输入“cd /home/zgq/linux/Linux_Drivers/回车” 切换到“/home/zgq/linux/Linux_Drivers/” 输入“ls回车”&#xff0c;查看“/home/zgq/linux/Linux_Drivers/” 输入“mkdi…

IDEA自带 .http 请求工具文档

基础语法 请求格式 基础格式 Method Request-URI HTTP-Version Header-field: Header-valueRequest-Body其中&#xff0c;GET 请求可以省略 Method 不写&#xff1b;HTTP-Version 可以省略不写&#xff0c;默认使用 1.1 版本。 示例&#xff1a; GET https://www.baidu.co…