【问题标题】:C Preprocessor to split "int x" into int & xC 预处理器将“int x”拆分为 int & x
【发布时间】:2013-12-05 22:35:26
【问题描述】:

我需要能够获得以下信息:

#define MY_MACRO(PARAM1,PARAM2) \
 MY_OTHER_MACRO(TYPENAME_OF(PARAM1),PARAMNAME_OF(PARAM1));\
 MY_OTHER_MACRO(TYPENAME_OF(PARAM2),PARAMNAME_OF(PARAM2));\

导致

MY_MACRO(int x,char *z) 

编译为

MY_OTHER_MACRO(int,x);
MY_OTHER_MACRO(char*,z);

不然编译成这样就不是世界末日了:

MY_OTHER_MACRO(int,x);
MY_OTHER_MACRO(char,*z);

或者即使这样也可以:(我可以编码 MY_OTHER_MACRO 来处理任一结果)

MY_OTHER_MACRO(int,x);
MY_OTHER_MACRO(char,z);

或者,如果有某种方法可以计算由空格分隔的标记(并假设“*”是单独的标记,我也可以使用它 - 例如 2 vs 3) 据我所知,通常情况下,标记用逗号分隔。有没有办法使用另一个字符?

【问题讨论】:

  • 不太可能。宏可以加入,而不是分开。
  • @zch 是的,但是他们可以加入,形成一个产生分离结果的宏的名称。

标签: c c-preprocessor variadic-macros


【解决方案1】:

您可以这样做,但只有一个极其困难的限制,即您必须提前知道所有类型名称:它不适用于任何用户定义的类型,除非用户也将它们添加到已知类型列表中- 诚然,这并不难。

接受这个限制,你可以这样做:

#define LPAREN (
#define RPAREN )
#define COMMA ,

#define CAT(L, R) CAT_(L, R)
#define CAT_(L, R) L ## R
#define EXPAND(...) __VA_ARGS__

#define SPLIT(OP, D) EXPAND(OP CAT(SPLIT_, D) RPAREN)

#define SPLIT_int LPAREN int COMMA
#define SPLIT_char LPAREN char COMMA
#define SPLIT_float LPAREN float COMMA
#define SPLIT_double LPAREN double COMMA

#define MY_MACRO(A, B) \
SPLIT(MY_OTHER_MACRO, A); SPLIT(MY_OTHER_MACRO, B);

MY_MACRO(int x, char * z)  // emits MY_OTHER_MACRO ( int , x ); MY_OTHER_MACRO ( char , * z );

如上所述,将类型添加到已知类型列表是单行 (#define SPLIT_myType LPAREN myType COMMA),只要在 SPLIT 实际使用该类型之前就可以在程序中的任何位置完成,所以这不是世界末日,尽管它具有很强的侵入性。

没有简单的方法可以让星号位于拆分的左侧。它可能可以完成,但它会复杂得多,并且涉及对允许的变量名称列表进行限制,这在 IMO 中要糟糕得多。可能也更具侵入性,因为您几乎可以肯定在工作程序中拥有比类型更多的变量。

【讨论】:

  • 当输入以点开头时,是否有办法让SPLIT 宏工作,例如:SPLIT(MY_OTHER_MACRO, .name)
【解决方案2】:

这是不可能的。

另一种方法是为类型和标识符设置不同的参数。

MY_MACRO(int, x, char *, z)

【讨论】:

  • 是的,这或多或少是我想要替换的。我会把这个问题留在这里,以防有答案,但我怀疑我只需要让最终用户代码看起来很笨拙,不像 c。
猜你喜欢
  • 2023-04-08
  • 2021-06-21
  • 2012-04-02
  • 2020-10-25
  • 2013-01-26
  • 2010-11-14
  • 2011-05-20
  • 1970-01-01
  • 2012-10-04
相关资源
最近更新 更多