当前位置: 首页 > news >正文

C++可变参数宏定义语法笔记

1. 基础语法

定义格式:

#define MACRO_NAME(fixed_args, ...) macro_body#define LOG(fmt, ...) printf(fmt, __VA_ARGS__)
LOG("Value: %d, Name: %s", 42, "Alice"); // 展开为 printf("Value: %d, Name: %s", 42, "Alice")

1)… 表示可变参数列表。
2)在宏体中,用 VA_ARGS 展开所有可变参数。

2. 处理空的可变参数

当可变参数为空时,直接使用 __VA_ARGS__ 可能导致语法错误(如尾随逗号)。可通过 ## 运算符优化:

使用 ##__VA_ARGS__

#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
LOG("Hello"); // 展开为 printf("Hello")(无尾随逗号)

## 在可变参数为空时,自动删除前面的逗号。

3. C++20 的 VA_OPT(可选展开)

C++20 引入 __VA_OPT__,可更灵活地控制可变参数的展开:

#define LOG(...) printf("Message: " __VA_ARGS__ __VA_OPT__(,) "\n")

当可变参数非空时,__VA_OPT__(,) 展开为 ,;为空时则不展开。

LOG("Error: %d", 404); // 展开为 printf("Message: " "Error: %d", 404 "\n")
LOG();                 // 展开为 printf("Message: " "\n")

4. 示例

(1) 调试日志

#define DEBUG(...) fprintf(stderr, "[DEBUG] " __VA_ARGS__)
DEBUG("File: %s, Line: %d\n", __FILE__, __LINE__);

(2) 泛型包装

#define CALL_FUNC(func, ...) func(__VA_ARGS__)
CALL_FUNC(printf, "Answer: %d", 42); // 展开为 printf("Answer: %d", 42)

(3) 条件编译

#ifdef VERBOSE#define LOG(...) printf(__VA_ARGS__)
#else#define LOG(...) (void)0
#endif

5. 注意事项

  1. 参数中的逗号:
    若参数包含未保护的逗号(如模板类型),需用括号包裹:
LOG("Types: %s", (std::vector<int>, std::map<std::string, float>));
  1. 兼容性:
    ##__VA_ARGS__是 GNU 扩展,但主流编译器(GCC、Clang、MSVC)均支持。
    __VA_OPT__ 是 C++20 标准特性,需编译器支持。

  2. 避免副作用:
    宏展开可能导致多次参数求值:

#define SQUARE_SUM(x, ...) ((x)*(x) + SQUARE_SUM(__VA_ARGS__))
// 错误:递归展开可能导致无限循环
#include <cstdio>// 可变参数宏:支持格式化字符串和可变参数
#define LOG(fmt, ...) printf("[INFO] " fmt "\n", ##__VA_ARGS__)int main() {LOG("Start");              // 输出: [INFO] StartLOG("Sum: %d", 3 + 5);     // 输出: [INFO] Sum: 8return 0;
}
http://www.xdnf.cn/news/615871.html

相关文章:

  • 【数据架构01】数据技术架构篇
  • Dify聊天系统SSE响应和聊天树数据结构图解
  • Spring的组成部分
  • Linux 的OTA升级学习1:Linux OTA升级方案_SWupdate
  • 聚焦 Microsoft Fabric,释放数据潜力
  • 篇一:重新学习的碎碎记
  • 【Web前端】JavaScript入门与基础(二)
  • 【AS32X601驱动系列教程】USART_串口通讯详解
  • 传统工程项目管理与业财一体化管理的区别?
  • 【知识点】关于vue3中markRow、shallowRef、shallowReactive的了解
  • [20250522]目前市场上主流AI开发板及算法盒子的芯片配置、架构及支持的AI推理框架的详细梳理
  • 深入解析 Linux 进程管理
  • 智能建筑时代来临,楼宇自控技术成智能建筑标配新趋势
  • redis主从复制架构安装与部署
  • 【跨端框架检测】使用adb logcat检测Android APP使用的跨端框架方法总结
  • 【通用智能体】Intelligent Internet Agent (II-Agent):面向复杂网络任务的智能体系统深度解析
  • 1.1 自动控制的一般概念
  • 【自定义类型-联合和枚举】--联合体类型,联合体大小的计算,枚举类型,枚举类型的使用
  • 电脑 IP 地址修改工具,轻松实现异地登陆
  • 如何实现 ERP 系统与淘宝订单、商品、物流接口对接
  • 大厂技术大神远程 3 年,凌晨 1 点到 6 点竟开会 77 次。同事一脸震惊,网友:身体还扛得住吗?
  • swagger-mcp-server
  • 《GDB 调试实战指南:无源码程序分析技巧与命令详解》
  • P3205 [HNOI2010] 合唱队
  • AI 驱动近红外光谱预处理:从数据清洗到特征工程的自动化
  • 2025版CansCodeAPI管理系统:免费下载,全新升级!
  • 八股--SSM(2)
  • 海外交友APP语言切换模块设计
  • 【AI大模型研究报告】2024年中国工业大模型行业发展研究报告
  • 善假于物也