我有一个用于调试的宏。
#define diagnostic_arg(message,...) fprintf(stderr,message,__VA_ARGS__)
我发现我需要在我的程序中使用宽字符,所以我想改变我的宏并让一切工作:
#define diagnostic_arg(message,...) fwprintf(stderr,message,__VA_ARGS__)
但是,我需要宽字符串,通过将L
放在字符串的开头引号前面来定义:
#define diagnostic_arg(message,...) fprintf(stderr,Lmessage,__VA_ARGS__)
现在显然,上面的行不起作用。但是,如果我使用L message
,那也无效。那么我该怎么写Lmessage
并让它做我想做的事呢?
答案 0 :(得分:14)
您可以使用token pasting operator ##
:
#define diagnostic_arg(message,...) fprintf(stderr,L##message,__VA_ARGS__)
但是,使用TEXT
宏(如果您在Visual Studio中)可能更好,无论是否定义UNICODE
,它都会做正确的事情:
#define diagnostic_arg(message,...) fprintf(stderr,TEXT(message),__VA_ARGS__)
如果不是,TEXT
可以这样定义:
#ifdef UNICODE
#define TEXT(str) L##str
#else
#define TEXT(str) str
#endif
然而,如果您打算使用其他#define
作为此宏的第一个参数(实际上即使您没有计划),您还需要另一个图层在宏中间接,因此将评估定义而不是与L
作为文本粘贴在一起。看看Mooing Duck的答案如何做到这一点,他实际上是正确的方法,但我没有删除这个答案,因为我想保留我的80代表。
答案 1 :(得分:7)
我含糊地回忆起答案是
//glues two symbols together that can't be together
#define glue2(x,y) x##y
#define glue(x,y) glue2(x,y)
//widens a string literal
#define widen(x) glue(L,x)
#define diagnostic_arg(message,...) fprintf(stderr,widen(message),__VA_ARGS__)
Glue 有时需要是两个宏(正如我所示),因为我不太明白的原因,解释at the C++faq