9

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

#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 对 3)通常,标记用逗号分隔,只要我知道。有没有办法使用另一个字符?

4

2 回答 2

13

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

接受此限制,您可以执行以下操作:

#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 中要糟糕得多。可能也更具侵入性,因为您几乎可以肯定在工作程序中具有比类型更多的变量。

于 2014-05-01T01:22:02.887 回答
0

这是不可能的。

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

MY_MACRO(int, x, char *, z)
于 2013-11-21T13:03:50.307 回答