我有一些需要使用Unicode字符串的代码,但是我想让它是有条件的(例如,TEXT("string")
展开为 L"string"
或 "string"
,具体取决于设置)。对于这些情况,我使用宏:
#ifdef _UNICODE
# define VSTR(str) L##str
#else
# define VSTR(str) str
#endif
这种情况的主要复杂性在于printf格式字符串,其中使用
%s
和%S
表示相同编码和其他编码字符串。一些字符串来自类似的有条件API(TCHAR
等),而一些来自集合API(大多仅限C-string)。当使用_tprintf
及其家族时,所使用的函数可能会有所变化,使得%s
和%S
也变成了有条件的,并且它们可能需要被翻转。为了处理这个问题,我定义了适当的格式元素宏:#ifdef _UNICODE
# define VPFCSTR(str) "%S"
# define VPFWSTR(str) "%s"
# define VPFTSTR(str) VPFWSTR(str)
#else
# define VPFCSTR(str) "%s"
# define VPFWSTR(str) "%S"
# define VPFTSTR(str) VPFCSTR(str)
#else
现在,这一切都很好运作,但是强制使用特定的语法:
VSTR("Beginning of a format string, with a string '") VPFTSTR VSTR("' included.")
我希望能够使用以下类似的语法:
```
VSTR("Beginning of a format string, with a string '", VPFTSTR, "' included.")
对于Unicode,这需要扩展为:
L"Beginning of a format string, with a string '" L"%s" L"' included."
唯一的复杂之处在于参数数量不确定,所有参数都需要以相同的方式进行转换(必要时逐个转换)。
我的第一个想法是使用
__VA_ARGS__
来处理这个问题,使用空参数,例如:VASTR(str, ...) VSTR(str) VASTR(__VA_ARGS__)
不幸的是,由于宏无法在其自身定义中使用,因此此方法失败。然后我尝试了一个代理:
VASTR2(...) VASTR(__VA_ARGS__)
VASTR(str, ...) VSTR(str) VASTR2(__VA_ARGS__)
代理方法似乎也不起作用。
有没有一种处理在另一个宏中运行相同宏的每个参数的方法,该宏接受可变数量的参数? 如果没有,是否有等效的方法? 如果特定于编译器,则首选MSVC10,但任何内容都很有趣。
printf
,我毫不同情。 - Puppyprintf
最终成为最优雅的解决方案(也许最好根本不记录日志)。:p - ssube