C/C++ 中#define 的妙用,让代码更美一些
C/C++ 中#define 的妙用,让代码更美一些
flyfish
1 数值类型输出易读的字符串形式
例如使用enum定义一些错误值,想要将数值类型的错误,输出易读的字符串形式
重要的一句代码
#define MAKE_PAIR(val) std::make_pair(val, #val)
可以看到 #val,宏定义中的传入参数名val 转换成字符串,就像用一对双引号包含起来的val
完整实现代码如下
#include <iostream>
#include <cinttypes>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
using namespace std;typedef enum {ACAMERA_OK = 0,ACAMERA_ERROR_BASE = -10000,ACAMERA_ERROR_UNKNOWN = ACAMERA_ERROR_BASE,ACAMERA_ERROR_INVALID_PARAMETER = ACAMERA_ERROR_BASE - 1,ACAMERA_ERROR_CAMERA_DISCONNECTED = ACAMERA_ERROR_BASE - 2,} camera_status_t;#define UKNOWN_TAG "UNKNOW_TAG"
#define MAKE_PAIR(val) std::make_pair(val, #val)
template <typename T>
const char* GetPairStr(T key, std::vector<std::pair<T, const char*>>& store) {typedef typename std::vector<std::pair<T, const char*>>::iterator iterator;for (iterator it = store.begin(); it != store.end(); ++it) {if (it->first == key) {return it->second;}}//LOGW("(%#08x) : UNKNOWN_TAG for %s", key, typeid(store[0].first).name());return UKNOWN_TAG;
}
using ERROR_PAIR = std::pair<camera_status_t, const char*>;
static std::vector<ERROR_PAIR> errorInfo{MAKE_PAIR(ACAMERA_OK),MAKE_PAIR(ACAMERA_ERROR_UNKNOWN),MAKE_PAIR(ACAMERA_ERROR_INVALID_PARAMETER),MAKE_PAIR(ACAMERA_ERROR_CAMERA_DISCONNECTED),
};
const char* GetErrorStr(camera_status_t err) {return GetPairStr<camera_status_t>(err, errorInfo);
}int main()
{std::cout<<GetErrorStr(ACAMERA_ERROR_INVALID_PARAMETER)<<std::endl;return 0;
}
输出
ACAMERA_ERROR_INVALID_PARAMETER
2 易记的简化调用
例如有两个函数
camera_status_t ACameraManager_A()
{std::cout<<"A"<<std::endl;return ACAMERA_OK;
}camera_status_t ACameraManager_B()
{std::cout<<"B"<<std::endl;return ACAMERA_OK;
}
这两个函数很长,函数名前缀相同
想要易记的简化调用
例如
CALL_MGR(A()); //实际调用ACameraManager_A()
CALL_MGR(B()); //实际调用ACameraManager_B()
#define CALL_CAMERA(func) \{ \camera_status_t status = func; \std::cout<<GetErrorStr(status)<<std::endl; \}
#define CALL_MGR(func) CALL_CAMERA(ACameraManager_##func)
#define 后面的 \ 表示下一行继续写宏定义。
两个#号 ## 表示连接操作符。 CALL_MGR(A());
通过 ACameraManager_##func
变成了ACameraManager_A
实现完整代码如下
#include <iostream>
#include <cinttypes>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
#include <assert.h>
using namespace std;typedef enum {ACAMERA_OK = 0,ACAMERA_ERROR_BASE = -10000,ACAMERA_ERROR_UNKNOWN = ACAMERA_ERROR_BASE,ACAMERA_ERROR_INVALID_PARAMETER = ACAMERA_ERROR_BASE - 1,ACAMERA_ERROR_CAMERA_DISCONNECTED = ACAMERA_ERROR_BASE - 2,} camera_status_t;#define UKNOWN_TAG "UNKNOW_TAG"
#define MAKE_PAIR(val) std::make_pair(val, #val)
template <typename T>
const char* GetPairStr(T key, std::vector<std::pair<T, const char*>>& store) {typedef typename std::vector<std::pair<T, const char*>>::iterator iterator;for (iterator it = store.begin(); it != store.end(); ++it) {if (it->first == key) {return it->second;}}//LOGW("(%#08x) : UNKNOWN_TAG for %s", key, typeid(store[0].first).name());return UKNOWN_TAG;
}
using ERROR_PAIR = std::pair<camera_status_t, const char*>;
static std::vector<ERROR_PAIR> errorInfo{MAKE_PAIR(ACAMERA_OK),MAKE_PAIR(ACAMERA_ERROR_UNKNOWN),MAKE_PAIR(ACAMERA_ERROR_INVALID_PARAMETER),MAKE_PAIR(ACAMERA_ERROR_CAMERA_DISCONNECTED),
};
const char* GetErrorStr(camera_status_t err) {return GetPairStr<camera_status_t>(err, errorInfo);
}camera_status_t ACameraManager_A()
{std::cout<<"A"<<std::endl;return ACAMERA_OK;
}
camera_status_t ACameraManager_B()
{std::cout<<"B"<<std::endl;return ACAMERA_OK;
}
#define CALL_CAMERA(func) \{ \camera_status_t status = func; \std::cout<<GetErrorStr(status)<<std::endl; \}
#define CALL_MGR(func) CALL_CAMERA(ACameraManager_##func)
int main()
{CALL_MGR(A());CALL_MGR(B());return 0;
}
输出
A
ACAMERA_OK
B
ACAMERA_OK
以上代码应用在google的ndk camera代码中
相关文章:

C/C++ 中#define 的妙用,让代码更美一些
C/C 中#define 的妙用,让代码更美一些 flyfish 1 数值类型输出易读的字符串形式 例如使用enum定义一些错误值,想要将数值类型的错误,输出易读的字符串形式 重要的一句代码 #define MAKE_PAIR(val) std::make_pair(val, #val)可以看到 #va…...

Linux文件系统操作与磁盘管理
查看磁盘和目录的容量 使用 df 命令查看磁盘的容量 df在实验楼的环境中你将看到如下的输出内容: 但在实际的物理主机上会更像这样: 物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示…...

【Python】批量采集原神表情包~
嗨害大家好鸭~我是小熊猫(✿◡‿◡) 最近迷上了原神, 不自觉中就很喜欢保存广大旅行者制作的表情包~ 真的很有意思诶~ 源码资料电子书:点击此处跳转文末名片获取 一个个保存的话,好像效率很低嘛… 那我就发挥我小熊猫的老本行直接给把他们全部采集下…...

C语言基本语法注释类型关键字
C 基本语法 标识符 给变量所取的名字叫变量名,定义变量的名字需要遵循标识符的命名规则。 标识符是用来标识变量、符号常量、数组、函数、文件等名字的有效字符序列。 标识符的命名规则: 1.只能由字母、数字和下划线组成(例如:…...

【C ++】C++入门知识(二)
C入门(二) 作者:小卢 专栏:《C》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 1.引用 1.1.引用的概念及应用 引用(&) 引用不是新定义一个变量࿰…...

qt qchart学习
Qt Charts主要由QChartView、QChart、QLegend图例、坐标轴(由QAbstractAxis子类实现)、**数据源(由QAbstractSeries子类实现)**等组成使用QChart的前期准备1. Qt5.9及以上版本;2. .pro文件中添加QT charts3. 在使用QChart的各个控件之前,引用头文件并必…...

手工布署 java 项目
新建一个java springboot项目 maven 这是一个非常简易的 springBoot 的项目 使用 maven 的 package 工具进行打包 把包上传到 linux 的机器上, 确保 linux 机器上安装了 java jdk工具, 并且配置好了 JAVA_HOME 注意,helloworld 默认的是要使…...

《设计模式》观察者模式
《设计模式》观察者模式 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象可以同时监听和相应被观察者对象的状态变化,以达到解耦和复用的目的。观察者模式的优点如下: 解耦:观察者模…...

基于SpringBoot的外卖项目(详细开发过程)
基于SpringBootMyBatisPlus的外卖项目1、软件开发整体介绍软件开发流程角色分工2、外卖项目介绍项目介绍产品展示后台系统管理移动端技术选型功能结构角色3、开发环境的搭建开发环境说明建库建表Maven项目搭建项目的目录结构pom.xmlapplication.ymlReggieApplication启动类配置…...

ChatGPT 研发传言席卷互联网公司,这会是一门好生意吗?
ChatGPT(也称GPT-3)是一种基于人工智能的自然语言生成模型,由OpenAI团队开发。它是GPT系列模型的最新版本,于2020年6月发布。ChatGPT的由来GPT-1是在2018年发布的第一个版本,使用了12亿个参数。随后,GPT-2在…...

获取servlet转发和响应重定向的方式是什么?
(1) 重定向和转发的区别 1)重定向是浏览器发送请求并受到响应以后再次向一个新地址发请求;转发是服务器受到请求后为了完成响应转到一个新的地址。 2)重定向中有两次请求对象,不共享数据;转发…...

jvm知识点
jvm面试总结 类加载机制? 如何把类加载到jvm中 ? 装载–>链接–>初始化–>使用–>卸载 装载: ClassFile–>字节流–>类加载器将字节流所代表的静态结构转化为方法区的运行时数据结构在我们的堆中生成一个代表这个类的java.lang.Class对象 链接: 验证–…...

MoveIT Noetic控制真实机械臂
文章目录 环境概述配置修改编写Action Server执行问题故障解决参考接前几篇: ROS MoveIT1(Noetic)安装总结 Solidworks导出为URDF用于MoveIT总结(带prismatic) MoveIT1 Assistant 总结 MoveIT Rviz和Gazebo联合仿真 环境 Ubuntu20.04;ROS1 Noetic;VMware...

如何快速入门编程
最近回答了很多小伙伴的问题,讲到如何快速入门编程?如何更好地学习视觉编程?如何提高编程技能?下面就和你聊聊,要做到这些,应该从哪些方面入手?询问他人我问过工程师们这些最基础的问题…...

java的反射Reflect
文章目录定义classClass获取一个类的类对象反射的具体步骤1.加载类类API2.实例化3.获取1)获取类中方法2)获取构造方法3)获取当前类的属性4.方法调用应用1.遍历对象属性,进行赋值定义 反射是操作其属性和方法从编码期决定转为在运行期决定 编码期决定:创…...

常用设计模式总结
复习到设计模式的时候写的一些demo代码 回头可以看看 单例的几种比较简单就没写了,专栏有 目录 观察者(发布--订阅模式)模式,多个对象依赖于一个对象,或者多对多 工厂模式:主要是封装了对象的创建&…...

【算法基础】一维前缀和 + 二维前缀和
👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:【C/C】算法 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有…...

Kafka消费分组和分区分配策略
Kafka消费分组,消息消费原理 同一个消费组里的消费者不能消费同一个分区,不同消费组的消费组可以消费同一个分区 (即同一个消费组里面的消费者只能在一个分区中) Kafka分区分配策略 问题 用过 Kafka 的同学用过都知道…...

犹太教、基督教、伊斯兰教的区别与联系
一、犹太教、基督教、伊斯兰教的简明关系图二、犹太教、基督教、伊斯兰教的主要区别注:弥赛亚(希伯莱语)就是基督(希腊语),意思是“救世主”。注:伊斯兰教的观点是:穆罕默德不是伊斯…...

华为OD机试 - 打印文件(Python) | 机试题+算法思路+考点+代码解析 【2023】
打印文件 题目 有 5 台打印机打印文件,每台打印机有自己的待打印队列。 因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的优先级,其中数字越大优先级越高。 打印机会从自己的待打印队列中选择优先级最高的文件来打印。 如果存在两个优先级一样的文件,则选…...

网络工程师必备知识点
作为网络工程师,您将负责设计、部署和维护计算机网络系统。这包括构建、配置和管理网络设备,如交换机、路由器、防火墙等,并确保网络系统能够高效地运行。您需要了解计算机网络的各个层次、协议、标准和技术,包括TCP/IP、DNS、HTT…...

数据在内存中的存储【下篇】
文章目录⚙️3.浮点型在内存中的存储🔩3.1.一个例子🔩3.2.浮点数的存储规则🔩3.3.例题解析⚙️3.浮点型在内存中的存储 🔩3.1.一个例子 🔴浮点数存储的例子:👇 int main() {int n 9;float* …...

前端开发项目规范写法介绍
1. 基本原则 结构、样式、行为分离 尽量确保文档和模板只包含 HTML 结构,样式都放到样式表里,行为都放到脚本里。 缩进 统一两个空格缩进(总之缩进统一即可),不要使用 Tab 或者 Tab、空格混搭。 文件编码 使用不带 BOM 的 UTF-8 编码。 在 HTML中指定编码 <meta c…...

百万医疗险是什么
一、百万医疗险是什么 从名字可以看出,这是一款医疗险。因为保额高,最高能报销百万,所以叫百万医疗险。 二、百万医疗险有什么用 可以报销被保险人因意外伤害和疾病导致的医疗费用 三、如何挑选 虽然高达几百万的保额,但保额却并非…...

矩阵中的路径 AcWing (JAVA)
请设计一个函数,用来判断在一个矩阵中是否存在一条路径包含的字符按访问顺序连在一起恰好为给定字符串。 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。 如果一条路径经过…...

使用终端工具给你的电脑发送弹窗提醒
大家好,我是良许。 现在人手一部智能手机,这些智能手机都有个非常实用的功能,那就是弹窗提醒。当我们收到短信,或者微信信息时,手机就会弹窗显示信息的大致内容。有了这个功能你就不会错过重要信息了。 电脑上也有类…...

SpringCloud Alibaba 之Nacos集群部署-高可用保证
文章目录Nacos集群部署Linux部署docker部署(参考待验证)Nacos 集群的工作原理Nacos 集群中 Leader 节点是如何产生的Nacos 节点间的数据同步过程官方推荐用户把所有服务列表放到一个vip下面,然后挂到一个域名下面。http://nacos.com:port/ope…...

Scala集合详解(第七章:集合、数组、列表、set集合、map集合、元组、队列、并行)(尚硅谷笔记)
集合第七章:集合7.1 集合简介7.1.1 不可变集合继承图7.1.2 可变集合继承图7.2 数组7.2.1 不可变数组7.2.2 可变数组7.2.3 不可变数组与可变数组的转换7.2.4 多维数组7.3 列表 List7.3.1 不可变 List7.3.2 可变 ListBuffer7.4 Set 集合7.4.1 不可变 Set7.4.2 可变 mutable.Set7.…...

定了:Python3.7,今年停止更新~
大家好,这里是程序员晚枫。 今天给大家分享一个来自Python官网的重要消息:Python3.7马上就要停止维护了,请不要使用了! 官网链接:https://devguide.python.org/versions/ 停更的后果是什么? 周末翻阅Py…...

C# 业务单据号生成器(定义规则、获取编号、流水号)
系列文章 C#底层库–数据库访问帮助类(MySQL版) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/126886379 C#底层库–JSON帮助类_详细(序列化、反序列化、list、datatable) 本文链接:htt…...