”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 如何在 C++ 宏中实现可选参数以进行代码定制?

如何在 C++ 宏中实现可选参数以进行代码定制?

发布于2024-12-21
浏览:832

How can you implement optional parameters in C   macros for code customization?

使用 C 宏自定义参数

宏是 C 编程的基本方面,允许代码自定义和灵活性。一个常见的要求是能够在宏中定义可选参数。

可选参数

考虑以下示例,其中我们有一个打印字符串的宏:

#define PRINT_STRING(message) PrintString(message, 0, 0)

该宏接受一个强制参数,要打印的消息。为了使其更加通用,我们可以引入字符串大小和字体样式的可选参数:

#define PRINT_STRING_1_ARGS(message)              PrintString(message, 0, 0)
#define PRINT_STRING_2_ARGS(message, size)        PrintString(message, size, 0)
#define PRINT_STRING_3_ARGS(message, size, style) PrintString(message, size, style)

用宏重载

为了实现重载,我们使用一个技巧来计算提供给宏的参数数量。然后,我们根据此参数计数选择适当的辅助宏:

#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
#define PRINT_STRING_MACRO_CHOOSER(...) \
    GET_4TH_ARG(__VA_ARGS__, PRINT_STRING_3_ARGS, \
                PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, )

用法

我们现在可以使用带有可选参数的重载 PRINT_STRING 宏:

#define PRINT_STRING(...) PRINT_STRING_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)

例如,我们可以不带参数调用宏来打印默认字符串:

PRINT_STRING("Hello, World!");

或者指定字符串大小:

PRINT_STRING("Hello, World!", 18);

或者字符串大小和字体样式:

PRINT_STRING("Hello, World!", 18, bold);

这种方法简化了参数处理宏调用者,增强代码的可重用性和多功能性。

最新教程 更多>
  • 为什么我的移动媒体查询无法在移动设备上运行?
    为什么我的移动媒体查询无法在移动设备上运行?
    移动媒体查询在移动设备上不起作用:故障排除提示许多开发人员面临移动设备上 CSS3 媒体查询无响应的问题。如果您遇到此问题,让我们根据您的查询探索潜在的解决方案:在您的样式表中,您正在使用移动设备的媒体查询,但在实际查看时它们似乎不起作用手机。相反,会显示默认 CSS。解决方案:验证媒体查询语法: ...
    编程 发布于2024-12-21
  • 为什么在 C++ 中使用 `` 时,`printf` 在 `std::printf` 和 `printf` 中都可以工作?
    为什么在 C++ 中使用 `` 时,`printf` 在 `std::printf` 和 `printf` 中都可以工作?
    cstdio Stdio.h 命名空间在 的 C 参考文档中,它声称所有库元素都驻留在 std 命名空间内。然而,实验表明 std::printf 和 printf 函数调用都可以工作。这是否表明 C 头文件将符号名称导入到 std 和全局命名空间中?答案包括 将符号名称导入到 std 命名空间...
    编程 发布于2024-12-21
  • Go 中下划线导入的目的是什么?
    Go 中下划线导入的目的是什么?
    理解下划线导入语句在 Go 编程世界中,导入语句前面的下划线字符 ( _ ) 具有特定的含义。让我们探讨一下它的含义和用法。下划线导入的目的导入语句中的下划线 (_ ) 表示导入该包只是为了其副作用。它不会从包中导入任何函数、方法或变量。Go 包中的副作用一些 Go 包具有初始化函数(通常名为 in...
    编程 发布于2024-12-21
  • CMake 如何处理 GCC 项目中的调试和发布构建?
    CMake 如何处理 GCC 项目中的调试和发布构建?
    了解 CMake 中的调试与发布在 GCC 编译项目中,CMake 为不同目标类型(调试/发布)配置构建设置提供了灵活性。以下是解决一些常见场景的方法:针对目标类型运行 CMake要为调试和发布版本创建单独的构建目录,请按照下列步骤操作:mkdir Release cd Release cmake ...
    编程 发布于2024-12-21
  • 我应该在 Python 脚本中使用 Shebang,如果是,使用哪一个?
    我应该在 Python 脚本中使用 Shebang,如果是,使用哪一个?
    我应该在 Python 脚本中包含 Shebang 吗?脚本中的 shebang 行允许直接从终端执行或通过文件管理器,无需显式指定 python 命令。虽然它的包含是可选的,但通常被认为是一种方便的做法。选择正确的 Shebang 形式shebang 行的形式对于确保脚本可移植性至关重要。正确的语...
    编程 发布于2024-12-21
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-12-21
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-12-21
  • 如何正确处理带有空白边界的 CSV 文件?
    如何正确处理带有空白边界的 CSV 文件?
    使用 Scanner() 读取 CSV 问题使用 Scanner() 读取 CSV 文件时,通常会遇到文本包含空格的问题被移动到下一行。发生这种情况是因为 Scanner 遵循空格边界。Scanner() 用法中的 CSV 处理不正确提供的代码片段使用 Scanner() 读取和处理 CSV 文件。...
    编程 发布于2024-12-21
  • 如何解决Hibernate中的LazyInitializationException?
    如何解决Hibernate中的LazyInitializationException?
    LazyInitializationException:无法从方法调用访问代理遇到“LazyInitializationException:无法初始化代理 - 无会话”错误通常表示Hibernate 应用程序中的延迟加载问题。当您尝试访问活动 Hibernate 会话范围之外的延迟初始化的实体(例如...
    编程 发布于2024-12-21
  • 为什么 Go 在包中定义字符串函数而不是方法?
    为什么 Go 在包中定义字符串函数而不是方法?
    Go中基本类型的方法编程语言Go包含多种字符串函数,例如ToUpper()和Split() 。与其他语言可能将这些函数定义为字符串类型的方法不同,Go 将它们定义为 strings 包的一部分。为什么会这样?简单性和灵活性根据 Go 的创建者的说法,将方法保留在字符串等基本类型之外的主要原因之一是维...
    编程 发布于2024-12-21
  • 大批
    大批
    方法是可以在对象上调用的 fns 数组是对象,因此它们在 JS 中也有方法。 slice(begin):将数组的一部分提取到新数组中,而不改变原始数组。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index p...
    编程 发布于2024-12-21
  • 将 Azure SQL 数据库升级到 v12 后,为什么会出现 TLS 握手错误?
    将 Azure SQL 数据库升级到 v12 后,为什么会出现 TLS 握手错误?
    v12 升级后 Azure SQL 数据库 TLS 握手错误Azure SQL 数据库实例升级到 v12 后,您可能会遇到 TLS 握手错误。当服务器提供的证书与客户端连接字符串中指定的主机名不匹配时,就会发生此错误。错误详细信息错误消息通常表明证书对于客户端连接中使用的主机名以外的主机名有效。例如...
    编程 发布于2024-12-21
  • 如何处理 SQL 数据库中多个表的外键关系?
    如何处理 SQL 数据库中多个表的外键关系?
    处理多个表的外键您有三个表:地区、国家和州。国家和国家可以属于地区,形成等级结构。现在,您想要创建一个包含“region_id”和“popular_place_id”列的“popular_areas”表,并基于“popular_place_type”列在“popular_place_id”与国家或州...
    编程 发布于2024-12-21
  • Go 是否为 Goroutine 特定数据提供 ThreadLocal 等效项?
    Go 是否为 Goroutine 特定数据提供 ThreadLocal 等效项?
    了解 Go 中的 Goroutine-本地存储在使用 Go 时,开发者经常会遇到需要跟踪与特定 Goroutine 相关的信息的情况。在 Java 等其他语言中,ThreadLocal 为该任务提供了一个优雅的解决方案。 Go 是否提供类似的机制?Go 的 Goroutine 本地存储方法Go 的标...
    编程 发布于2024-12-21
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSocke...
    编程 发布于2024-12-21

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3