我需要能够获得以下内容:
#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) 通常,据我所知,令牌用逗号分隔。有没有办法使用另一个角色?
答案 0 :(得分:9)
您可以这样做,但只有极其困难的限制,您必须事先知道所有类型名称:它不适用于任何用户定义的类型,除非用户也将它们添加到已知类型的列表中 - 这当然不难。
接受此限制,您可以执行以下操作:
#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
),并且可以在程序中的任何位置完成,只要在{实际使用该类型之前到达它{1}},所以它不是世界末日,尽管它是高度侵入性的。
没有简单的方法可以让星号位于分割的左侧。它可能会完成,但它会更复杂,并且涉及将限制放在允许的变量名称列表上,IMO更加糟糕。可能也更具侵入性,因为你几乎肯定会有更多的变量而不是工作程序中的类型。
答案 1 :(得分:0)
这是不可能的。
一种替代方法可能是为类型和标识符设置不同的参数。
MY_MACRO(int, x, char *, z)