可变参数宏:粘贴标记的扩展

2023-12-14

我想知道是否可以“嵌套”可变参数宏调用。我只真正关心 GCC 和 Clang。我的宏定义如下:

/**
 * @brief Invoke an instance method.
 */
#define $(obj, method, ...) \
    ({ \
        typeof(obj) _obj = obj; \
        _obj->interface->method(_obj, ## __VA_ARGS__); \
    })

我用它来方便地调用我的 OO 框架中的“实例方法”(https://github.com/jdolan/objectively):

$(array, addObject, obj);

工作老板。不幸的是,我还没有找到一种允许嵌套这些调用的方法,这在某些情况下非常有用;例如。:

/**
 * @see MutableSetInterface::addObjectsFromArray(MutableSet *, const Array *)
 */
static void addObjectsFromArray(MutableSet *self, const Array *array) {

    if (array) {
        for (size_t i = 0; i < array->count; i++) {
            $(self, addObject, $(array, objectAtIndex, i));
        }
    }
}

上面的嵌套可变参数宏调用无法编译,因为内部调用永远不会扩展。是否可以解决这个问题,或者我是否已经滥用预处理器到其极限? :)


这是嵌套预处理器宏的常见问题。预处理器扩展规则相当神秘;相关的tl;dr是宏是分层扩展的。解决方法是添加一个可以扩展参数的间接层:

#define MI(obj, method, ...) \
  ({ \
    typeof(obj) _obj = obj; \
    _obj->interface->method(_obj, ## __VA_ARGS__); \
  })

#define M(obj, method, ...) MI(obj, method, __VA_ARGS__)

// This will now expand properly.
M(self, addObject, M(array, objectAtIndex, M(foo, bar, i)))

旁注:请注意$不是 C 的基本源字符集的一部分;使用它可能不方便携带。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可变参数宏:粘贴标记的扩展 的相关文章

  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • Rust 中声明变量的宏?

    在 C 中 可以编写声明变量的宏 如下所示 define VARS a b c int a b c 当然 这不是您通常想要做的事情 在实际的例子中 我希望开始工作 但它并不那么简单 define VARS data stride a b c
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • 如何在多用户环境(500+)中处理 Eclipse?

    您将如何在拥有 500 名或更多开发人员的多用户和多站点环境中处理 Eclipse 让每个人下载自己的安装将导致一场支持和维护的噩梦 强迫每个人都使用集中安装感觉也不理想 并且会限制用户下载插件的选择 Edit 问题不是强迫用户选择Ecli
  • 如何使用 ZipKit 在 iOS 中压缩目录?

    我需要在 iOS 应用程序中压缩文档文件夹的子目录 在咨询了 Google 和其他 SO 帖子后 我发现 ZipKit 和 ZipArchive 作为两个提供此功能的开源项目 此时 我选择实现 ZipKit 因为它目前似乎比 ZipArch
  • 用 Java 找出您网站访问者的 IP 地址

    有没有简单可靠的方法来使用 Java 检测您的网站访问者 IP 地址 我正在尝试利用 Akismet 来检测我的博客文章 评论中的垃圾邮件 API 要求我指定评论者的 IP 地址 谢谢 致电ServletRequest getRemoteA
  • 如何在我的 Android 应用程序的可视化 C# Web 服务中调用 LINQ 中的用户定义函数?

    我目前正在开发一个应用程序 该应用程序将根据距离检索其他用户的位置 我有一个数据库 以纬度和经度存储所有用户位置信息 由于这两对经纬度之间距离的计算相当复杂 所以我需要一个函数来处理它 from a in db Location Where
  • 单击 #-links 时避免窗口跳转到顶部

    我有一个包含一些问题和答案的页面 默认情况下答案是折叠的 当他们单击问题时 我展开隐藏的答案 div 问题是 当我点击这些问题时 窗口跳到屏幕顶部 这不是一个大问题 但我觉得很烦人 因为我必须再次向下滚动到问题 链接看起来就像这样 a hr
  • 如何获取iPhone应用隐藏状态栏区域的触摸事件?

    我有一个隐藏状态栏的 iPhone 应用程序 但是 当我点击状态栏区域时 我的主视图没有收到任何触摸事件 我可以做些什么来解决这个问题吗 以下是我的应用程序设置的一些详细信息 如果重要的话 它是一个基于 OpenGL 的应用程序 该应用程序
  • 如何从 PHP 连接 Jms?

    我正在尝试在我的网站上实现像 Facebook 使用的小聊天功能 我使用了 Html PHP JQuery 和 Apache 我之前用 JMS 做了一些例子 但我不知道如何用 PHP 向 JMS 服务器发送消息 对于 JMS 我使用 Web
  • 将 BigInteger 二进制转换为 BigInteger 数字

    目前我正在使用Long整数类型 我使用以下命令来转换二进制 数字 Convert ToInt64 BinaryString 2 Convert binary string of base 2 to number Convert ToStri
  • java.util.Date 和 java.time.Instant 之间转换古代日期时出现差异

    我有使用 java util Date 创建古代日期 0002 年 11 月 30 日 的遗留代码 我正在尝试更新我可以更新的代码 但这需要在 Date 和 LocalDate 等之间进行转换 我无法完全摆脱使用 Date 或古老的日期选择
  • Spring Integration / JSch:身份验证失败

    我正在尝试使用 Spring Integration 的 SFTP 入站通道适配器 但我被困在这里 20 29 30 458 INFO com jcraft jsch task scheduler 6 Connecting to deplo
  • 在基于 Flask 的应用程序中获取客户端 IP

    我在服务器中部署了 Flask 应用程序 我们正在使用 Nginx nginx 设置如下 proxy set header X Forward For proxy add x forwarded for proxy set header H
  • 在 Windows x86-64 下,发生异常时,有多少内容被推送到 32 位堆栈上?

    In this 这个问题 我给出了一些我已经实现的并行语言的背景知识 编译器生成本机 x86 32 代码 一个关键的实现决策是为每个函数 调用 从堆中分配堆栈空间 这允许递归直到你用完虚拟机 并为词法范围启用仙人掌堆栈 甚至对于嵌套的并行子
  • 使用 Jenkins 管道脚本从 Windows 到 Linux 的 SCP

    我想要做SCP从 Windows Jenkins 节点到 Linux 服务器 在此设置中 Windows 计算机是 Jenkins 从机 我要复制的目标服务器是 Linux 下面是我的 Jenkins 管道脚本 在运行下面的脚本之前 我将克
  • 无法将 dbt cloud 或 dbt core 连接到 databricks

    我在将 dbt cloud 和 dbt core 连接到 databricks 时遇到问题 我已阅读这 4 个链接 但仍然无法连接 https docs databricks com integrations prep dbt html h
  • GridView无法显示图像

    我获取所有应用程序的图标 并在 GridView 中显示图标 GridView 很好地显示了它们 但是当我非常快地向下滑动 GridView 时 有时 GridView 缺少两个图标 这种情况不常出现 您能给我一些建议吗 EDIT 这个问题
  • Google c# Api,从 v2.3 更改为 v3

    我有以下代码使用 C v2 3 api 查询谷歌分析 string username email protected string pass PASS string gkey key XXXXXXXXXXXXXXXXXXXXXXXXXXX
  • SkiaSharp Tiff 支持

    目前 SkiaSharp 不支持 tiff 图像 它支持 jpg gif bmp png 和其他一些格式 如何将 tiff 图像转换为 SKBitmap 对象 一个想法 也许有一种有效的方法来转换 tiff 流 gt png 流 gt SK
  • Descendants 在 Word 文档中获取零个元素

    我在更新 Word 文档中的超链接时遇到问题 Q如何更新 Word 文档中的正文和超链接 并放大Descendants
  • ORA-00907: 创建外键 Oracle 12c 时缺少右括号

    我想制作一张包含一个自动生成的主键和两个外键的表 但我遇到了这个错误 create table answers id number generated by default on null as identity primary key q
  • 可变参数宏:粘贴标记的扩展

    我想知道是否可以 嵌套 可变参数宏调用 我只真正关心 GCC 和 Clang 我的宏定义如下 brief Invoke an instance method define obj method typeof obj obj obj obj