Vin*_*inz 9 c c++ macros stringification c-preprocessor
我正在使用这个预处理器宏来"字符串化"并从定义解析函数中轻松返回:
#define STRINGIFY_RETURN(x) case x: return #x ""
Run Code Online (Sandbox Code Playgroud)
它就像MBSC环境中的魅力一样,具有正常的字符串文字.例:
#define MY_DEFINE_1 1
#define MY_DEFINE_2 2
#define MY_DEFINE_3 3
const char* GetMyDefineNameA(unsigned int value)
{
switch(value)
{
STRINGIFY_RETURN(MY_DEFINE_1);
STRINGIFY_RETURN(MY_DEFINE_2);
STRINGIFY_RETURN(MY_DEFINE_3);
default: return "Unknown";
}
}
Run Code Online (Sandbox Code Playgroud)
但是我不得不越来越多地切换到Unicode兼容性,所以我不得不重写这个函数来返回Unicode字符串,这需要L在字符串文字前加前缀.所以我尝试过:
#define STRINGIFY_RETURN_WIDE(x) case x: return #x L""
const wchar_t* GetMyDefineNameW(unsigned int value)
{
switch(value)
{
STRINGIFY_RETURN_WIDE(MY_DEFINE_1);
STRINGIFY_RETURN_WIDE(MY_DEFINE_2);
STRINGIFY_RETURN_WIDE(MY_DEFINE_3);
default: return L"Unknown";
}
}
Run Code Online (Sandbox Code Playgroud)
但这给了我错误:
错误C2308:连接不匹配的字符串
错误C2440:'return':无法从'const char [12]'转换为'const wchar_t*
我也尝试过:
#define STRINGIFY_RETURN_WIDE(x) case x: return L #x ""
#define STRINGIFY_RETURN_WIDE(x) case x: return #x "" L
Run Code Online (Sandbox Code Playgroud)
但无论如何,我都无法让它发挥作用.我对此毫无头绪,似乎无法找到解决方案.
如果有人能够显示正确的方法来执行此宏以使其解析为Unicode字符串文字,我将非常感激.
更新:
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x ""
Run Code Online (Sandbox Code Playgroud)
不会抛出C2440错误,但它仍然给我C2308.
更新2:
我正在使用Microsoft Visual Studio 2013
您有两个主要选择:
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x L""
Run Code Online (Sandbox Code Playgroud)
这连接两个L"…"字符串.另一种更简单的解决方案是不连接空字符串:
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x
Run Code Online (Sandbox Code Playgroud)
不清楚附加空字符串有什么好处.
正如RobertPrévost在评论中指出的那样,这不适用于G ++和Clang ++,尽管它似乎适用于Vinzenz的编译器(Microsoft Visual Studio 2013).
问题是预处理器将其输入标记化,宽字符串文字L"..."只是一个标记,但上面的宏试图生成标记L和"..."`,导致问题:
xx11.cpp:5:49: error: ‘L’ was not declared in this scope
#define STRINGIFY_RETURN_WIDE(x) case x: return L#x
^
xx11.cpp:11:9: note: in expansion of macro ‘STRINGIFY_RETURN_WIDE’
STRINGIFY_RETURN_WIDE(MY_DEFINE_1);
Run Code Online (Sandbox Code Playgroud)
有一个解决方法:
#define MY_DEFINE_1 1
#define MY_DEFINE_2 2
#define MY_DEFINE_3 3
#define LSTR(x) L ## x
#define STRINGIFY_RETURN_WIDE(x) case x: return LSTR(#x)
const wchar_t* GetMyDefineNameW(unsigned int value)
{
switch(value)
{
STRINGIFY_RETURN_WIDE(MY_DEFINE_1);
STRINGIFY_RETURN_WIDE(MY_DEFINE_2);
STRINGIFY_RETURN_WIDE(MY_DEFINE_3);
default: return L"Unknown";
}
}
Run Code Online (Sandbox Code Playgroud)
使用GCC 6.2.0在Mac OS X 10.11.6上进行检查.