2013-11-21 68 views
2

我需要能够得到如下:C预处理器分裂 “INT X” 转换成int&X

#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与任一结果工作)

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

可替代地,如果有计数由空格分隔令牌的某种方式(并假定“*”是单独的标记,我也可以使用它 - 例如2 vs 3) 通常,令牌由逗号分隔,据我所知。有什么方法可以使用另一个角色?

+2

不太可能。宏可以加入,而不是分开。 – zch

回答

0

这是不可能的。

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

MY_MACRO(int, x, char *, z) 
+0

是的,或多或少我想要取代。我将在这里留下这个问题,以防万一答案即将出现,但我怀疑我只是要让最终用户代码看起来不太明显,而不是像C一样。 – unsynchronized

8

你可以这样做,但只有你必须知道所有的类型名称预先极其困难的限制:除非用户将其添加到列表中,将不与任何用户定义类型工作已知类型也是如此 - 这当然不难。

接受这种限制,你可以做这样的事情:

#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的情况要严重得多。也许更具侵入性,因为在工作程序中几乎肯定会有比类型更多的变量。