C++开发小技巧

C++开发一些小技巧

积累一些能用得到的C++开发小技巧。

错误码/状态码

错误码/状态码在项目很常见,用于提示错误类型、状态,通常还会附带一些相关描述。通常错误码是统一管理的,例如使用宏或者枚举定义。

平时我的做法

  • 使用宏或者枚举定义错误码、状态码
  • 使用map或者数组定义错误码的提示信息,通过GetMsg获取错误提示
namespace statis_code {
enum ServiceCode {
  kSuccess = 0,
  // client exccept
  kBadParams = 1000,
  kIllegalAuth = 1001,

  // service except
  kServerExcept = 2001
};

const std::unordered_map<ServiceCode, std::string> kCodeMsg{
    {kSuccess, "ok"},
    {kBadParams, "except request params,check uri"},
    {kIllegalAuth, "auth failed"},
    {kServerExcept, "service unavailable"}};

std::string GetMsg(ServiceCode code) {
  auto itr = kCodeMsg.find(code);
  return itr == kCodeMsg.end() ? "unknown status" : itr->second;
}
} // namespace statis_code

brpc的做法

上述做有几个不太好的地方,首先是错误码定义较为随意,有可能和系统错误码冲突.linux自身0-132有自己的定义;其次我们需要自己去保证错误码的不重复,当错误码较多且多人开发时可能会有冲突,但是这种冲突很难发现;用户可能还会继续拓展错误码,这时需要修改枚举和map。所以我们更希望: 错误码能在编译层面保证不重复;错误码定义希望是注册式的,提供给用户注册接口和获取msg接口。
无意间看到brpc定义错误码时使用了模板特例化保证不重复,同时也是注册式的写法。

  • 模板特例化的应用
    模板特例化
template <int status_code> class ServiceCodeHelper {};
template <> class ServiceCodeHelper<statis_code::ServiceCode::kBadParams> {};
template <> class ServiceCodeHelper<statis_code::ServiceCode::kBadParams> {}; // 报错,重复定义

通过模板特例化,可能在编译期间发现重复定义的错误码。那么接下来做法上第一种做法类似,注册错误码描述即可。下面是注册函数:
errno_desc数组存储对错误码的描述,在注册时先做范围检测、重复描述检测、是否系统错误码检测,然后将描述写入数组。

const int ERRNO_BEGIN = -32768;
const int ERRNO_END = 32768;
static const char* errno_desc[ERRNO_END - ERRNO_BEGIN] = {};
static pthread_mutex_t modify_desc_mutex = PTHREAD_MUTEX_INITIALIZER;

const size_t ERROR_BUFSIZE = 64;
__thread char tls_error_buf[ERROR_BUFSIZE];

int DescribeCustomizedErrno(
    int error_code, const char* error_name, const char* description) {
    BAIDU_SCOPED_LOCK(modify_desc_mutex);
    if (error_code < ERRNO_BEGIN || error_code >= ERRNO_END) {
        // error() is a non-portable GNU extension that should not be used.
        fprintf(stderr, "Fail to define %s(%d) which is out of range, abort.",
              error_name, error_code);
        _exit(1);
    }
    const char* desc = errno_desc[error_code - ERRNO_BEGIN];
    if (desc) {
        if (strcmp(desc, description) == 0) {
            fprintf(stderr, "WARNING: Detected shared library loading\n");
            return -1;
        }
    } else {
#if defined(OS_MACOSX)
        const int rc = strerror_r(error_code, tls_error_buf, ERROR_BUFSIZE);
        if (rc != EINVAL)
#else
        desc = strerror_r(error_code, tls_error_buf, ERROR_BUFSIZE);
        if (desc && strncmp(desc, "Unknown error", 13) != 0)
#endif
        {
            fprintf(stderr, "WARNING: Fail to define %s(%d) which is already defined as `%s'",
                    error_name, error_code, desc);
        }
    }
    errno_desc[error_code - ERRNO_BEGIN] = description;
    return 0;  // must
}

获取错误信息时首先查我们自己定义的数组然后再查是否时系统错误码。

const char* berror(int error_code) {
    if (error_code == -1) {
        return "General error -1";
    }
    if (error_code >= butil::ERRNO_BEGIN && error_code < butil::ERRNO_END) {
        const char* s = butil::errno_desc[error_code - butil::ERRNO_BEGIN];
        if (s) {
            return s;
        }
#if defined(OS_MACOSX)
        const int rc = strerror_r(error_code, butil::tls_error_buf, butil::ERROR_BUFSIZE);
        if (rc == 0 || rc == ERANGE/*bufsize is not long enough*/) {
            return butil::tls_error_buf;
        }
#else
        s = strerror_r(error_code, butil::tls_error_buf, butil::ERROR_BUFSIZE);
        if (s) {
            return s;
        }
#endif
    }
    snprintf(butil::tls_error_buf, butil::ERROR_BUFSIZE,
             "Unknown error %d", error_code);
    return butil::tls_error_buf;
}

错误码注册

#define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
#define BAIDU_CONCAT_HELPER(a, b) a##b

#define REGISTER_CODE(code, desp)                                              \
  \ 
const int BAIDU_CONCAT(error_code_flag, __LINE__) =                            \
      DescribeCustomizedErrno((code), (desp));                                 \
  template <> class ServiceCodeHelper<int(code)> {};

REGISTER_CODE(ServiceCode::kBadParams, "bad uri")
REGISTER_CODE(ServiceCode::kBadParams, "bad uri desp")  // 重复定义

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rust 注释文档生成 cargo doc

rust的cargo文档生成 只需要在每个函数写清楚注释&#xff0c;就可以自动生成文档&#xff0c;很方便 即不用写文档&#xff0c;又可以快速查看&#xff0c;是开发rust的必备技能 rust安装和开发环境配置&#xff0c;可以参考&#xff1a;链接 1.写注释的方法 连续三个 \ 即…

springboot + vue3实现增删改查分页操作

springboot vue3实现增删改查分页操作 环境最终实现效果实现功能主要框架代码实现数据库后端前端 注意事项 环境 jdk17 vue3 最终实现效果 实现功能 添加用户&#xff0c;禁用&#xff0c;启用&#xff0c;删除&#xff0c;编辑&#xff0c;分页查询 主要框架 后端 spri…

在vue3中使用Cesium保姆篇

1.首先新建一个vue项目 Vue.js - 渐进式 JavaScript 框架 | Vue.js 可以直接到管网中查看命令通过npm来创建一个vue3的项目 然后通过命令下载1.99的版本的cesium和plugin npm i cesium1.99 vite-plugin-cesium 下载完了以后 2.引入cesium 首先找到vue的vite.config.js …

技术资讯:谷歌最新发布!2023年度最受欢迎的Chrome扩展榜单

大家好&#xff0c;我是大澈&#xff01; 本文约1300字&#xff0c;整篇阅读大约需要2分钟。 感谢关注微信公众号&#xff1a;“程序员大澈”&#xff0c;免费领取"面试礼包"一份&#xff0c;然后免费加入问答群&#xff0c;从此让解决问题的你不再孤单&#xff01…

windows 在指定目录下打开 cmd,不用层层进入

一、进入需要打开的目录下 二、在选中的状态下&#xff0c;输入 cmd&#xff0c;然后回车即可

63.接口安全设计(活动管理系统:三)

文章目录 一、参数校验二、统一封装返回值三、做权限控制四、加验证码五、 限流六、加ip白名单七、校验敏感词八、使用https协议九、数据加密十、做风险控制 在日常工作中&#xff0c;开发接口是必不可少的事情&#xff0c;无论是RPC接口还是HTTP接口&#xff0c;我们都应该考虑…

x-cmd pkg | trafilatura - 网络爬虫和搜索引擎优化工具

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 trafilatura 是一个用于从网页上提取文本的命令行工具和 python 包: 提供网络爬虫、下载、抓取以及提取主要文本、元数据和评论等功能可帮助网站导航和从站点地图和提要中提取链接无需数据库&#xff0c;输出即可转换…

python总结高阶-文件

文章目录 文件操作文本文件和二进制文件1 文本文件2 二进制文件 文件操作相关模块创建文件对象open()文本文件的写入基本的文件写入操作常用编码介绍write()/writelines()写入数据close()关闭文件流with语句(上下文管理器) 文本文件的读取read([size])readline()readlines() 二…

用友U8 Cloud smartweb2.RPC.d XXE漏洞复现

0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 Cloud smartweb2.RPC.d接口处存在 XXE漏洞,攻击者可通过该漏洞获取敏感文件…

Typora 编辑器 讲解 包括使用方式 快捷键 附带下载地址 (免费破解)

CSDN 成就一亿技术人&#xff01; 今天来讲一下很好用的编辑器 Typora CSDN 成就一亿技术人&#xff01; 什么是Typora&#xff1f; 它是一个 Markdown 编辑器和阅读器&#xff0c;这意味着您可以使用简单的格式代码 &#xff08;Markdown&#xff09;是一种轻量级标记语言&…

安科瑞汽车充电桩在西北地区的应用——安科瑞 顾烊宇

摘要&#xff1a;“十四五”是经济发展追赶超越的关键时期&#xff0c;将进一步促进电动汽车及充电市场的繁荣发展。目前我国正处于转型发展的关键时期&#xff0c;在“新基建”的推动下&#xff0c;新能源汽车充电桩的建设将迎来发展机遇。本文首先通过统计、分析西部城市某辖…

bat批处理文件_bat注释汇总

文章目录 1、示例&#xff08;直接结合脚本和结果进行理解&#xff09; 1、示例&#xff08;直接结合脚本和结果进行理解&#xff09; %这是一个注释% %这是另一个注释%rem 这是一个注释 rem 这是另一个注释:这是一个注释 ::这是一个注释 :?这是另一个注释if 1 1 ( %这里会执…

VMware 安装 macOS虚拟机(附工具包)

VMware 安装 macOS虚拟机&#xff0c;在Windows上体验苹果macOS系统&#xff01; 安装教程&#xff1a;VMware 安装 macOS虚拟机VMware Workstation Pro 是一款强大的虚拟机软件&#xff0c;可让您在 Windows 电脑上运行 macOS 系统。只需简单几步操作&#xff0c;即可轻松安装…

大型语言模型的幻觉问题

1.什么是大模型幻觉&#xff1f; 在语言模型的背景下&#xff0c;幻觉指的是一本正经的胡说八道&#xff1a;看似流畅自然的表述&#xff0c;实则不符合事实或者是错误的。 幻觉现象的存在严重影响LLM应用的可靠性&#xff0c;本文将探讨大型语言模型(LLMs)的幻觉问题&#x…

Mybatis-Plus乐观锁配置使用流程【OptimisticLockerInnerInterceptor】

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家:人工智能学习网站 1.乐观锁实现 1.配置插件 1.XML方式 <bean class"com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerI…

CRM如何精确控制RT设备和与UMD通信笔记

1 CRM工作职责 监控link req是否得到schedule监控link上各个device的req是否ready监控SOF或EOF的trigger信号&#xff0c;决定各个设备配置哪个req 2 CRM如何精确控制RT设备 分两步&#xff0c;一是crm知道某帧req的link dev准备好了&#xff0c;可以做apply setting。 二是…

获取小红书笔记详情API调用说明(含请求示例参数说明)

前言 小红书&#xff0c;是一个引领全球时尚潮流的社交电商平台。在这里&#xff0c;你可以发现世界各地的优质好物&#xff0c;从美妆护肤、穿搭时尚&#xff0c;到家居生活、旅行美食&#xff0c;一切应有尽有。同时&#xff0c;这里也是一个分享生活点滴的平台&#xff0c;…

YOLOv5+混合注意力机制再涨4.3%,Transformer混合设计依旧可以卷

在工业生产过程中&#xff0c;由于低效率、不统一的评估、高成本以及缺乏实时数据&#xff0c;传统的手动检测焊接缺陷不再被应用。 为了解决表面贴装技术中焊接缺陷检测的低准确率、高误检率和计算成本问题&#xff0c;提出了一种新方法。该方法是一种专门针对焊接缺陷检测算法…

集团企业OA办公协同平台建设方案

一、企业对协同应用的需求分析 实现OA最核心、最基础的应用 业务流转&#xff1a;收/发文、汇报、合同等各种审批事项的业务协作与办理 信息共享&#xff1a;规章制度、业务资料、共享信息资源集中存储、统一管理 沟通管理&#xff1a;电子邮件、手机短信、通讯录、会议协作等…

es集群安装及优化

es主节点 192.168.23.100 es节点 192.168.23.101 192.168.23.102 1.安装主节点 1.去官网下载es的yum包 官网下载地址 https://www.elastic.co/cn/downloads/elasticsearch 根据自己的需要下载对应的包 2.下载好之后把所有的包都传到从节点上&#xff0c;安装 [rootlocalho…