【问题标题】:variadic macro that handles last argument in a different way以不同方式处理最后一个参数的可变参数宏
【发布时间】:2020-04-30 18:12:23
【问题描述】:

如果有一种方法可以定义以不同方式处理其最后一个参数的可变参数宏,我正在徘徊。

例如,我可以定义一个宏,在除最后一个参数之外的每个参数之后打印自定义分隔符吗?

即如何定义宏:

MACRO(a, lot, of, bars)

为了产生这个输出:

a|lot|of|bars

(编辑:cmets 向我指出,, 作为分隔符的情况是微不足道的)

【问题讨论】:

  • @R..GitHubSTOPHELPINGICE 我的错,我编辑了原帖,谢谢。我的问题是关于任何分隔符。
  • 对于新形式的问题,最后一个槽没有什么特别的;困难在于根本进行转换。
  • @jxh 错过了之前的编辑,真的很抱歉
  • 请澄清您的意思是按位或所示的表达式,还是具有该内容的字符串
  • @M.M 包含该内容的字符串,但考虑到宏没有这样的语义(它们只处理原始文本),它是否会有所不同?

标签: c gcc macros c-preprocessor


【解决方案1】:

您可以应用宏参数计数技巧。最多五个宏参数(原始答案支持 4 个宏参数,因此您可以查看差异以了解如何扩展宏以获得其他参数):

#define MACRO(...) MACRO_X(__VA_ARGS__,5,4,3,2,1)(__VA_ARGS__)

#define MACRO_X(_5,_4,_3,_2,_1,X,...) MACRO_##X

#define MACRO_5(X,...) X|MACRO_4(__VA_ARGS__)
#define MACRO_4(X,...) X|MACRO_3(__VA_ARGS__)
#define MACRO_3(X,...) X|MACRO_2(__VA_ARGS__)
#define MACRO_2(X,...) X|MACRO_1(__VA_ARGS__)
#define MACRO_1(X,...) X

要创建字符串,可以使用“stringify”操作符:

#define STR2(X) STR(X)
#define STR(X) #X

所以:

puts(STR2(MACRO(a,lot,of,bars)));

【讨论】:

  • 我用cpp 尝试了你的答案,并从1 到4 个参数调用MACRO,但我收到了这个错误:error: unterminated argument list invoking macro "PASTE"
  • 我有一个错字,但还有几件事要补充。答案已更新。
  • 这里或多或少地描述了技术:stackoverflow.com/q/11761703/315052
【解决方案2】:

如果输出不需要字符串化,那么可以相对简单地产生一个等价的表达式:

#define MACRO(...) BIGMACRO(__VA_ARGS__,0,0,0,0,0,0,0,0)
#define BIGMACRO(a0,a1,a2,a3,a4,a5,a6,a7,...) a0|a1|a2|a3|a4|a5|a6|a7

所以 MACRO(a,lot,of,bars) 扩展为 a|lot|of|bars|0|0|0|0 ,其类型和值与 a|lot|of|bars 相同。

【讨论】:

  • 我能够将您的解决方案转换为字符串化版本,但我仍然需要做一个计数技巧...tio.run/##bY9Pa8MwDMXv/…
  • @jxh phat,也许可以发布另一个答案!
猜你喜欢
  • 2014-07-23
  • 2014-11-10
  • 2015-11-09
  • 1970-01-01
  • 2014-12-22
  • 2010-10-20
  • 2011-08-18
  • 2013-05-21
  • 2017-11-24
相关资源
最近更新 更多