c++ - 使用 Unicode 字符串文字 Stringify 宏

标签 c++ c macros c-preprocessor stringification

我正在使用这个预处理器宏来“字符串化”并轻松地从定义解析函数返回:

#define STRINGIFY_RETURN(x) case x:     return #x ""

它在具有普通字符串文字的 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";
    }
}

然而,我不得不越来越多地切换到 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";
    }
}

但这给了我错误:

error C2308: concatenating mismatched strings

error C2440: 'return' : cannot convert from 'const char [12]' to 'const wchar_t *

我也试过:

#define STRINGIFY_RETURN_WIDE(x)    case x:     return L #x ""
#define STRINGIFY_RETURN_WIDE(x)    case x:     return #x "" L

但无论如何,我无法让它工作。我对此一无所知,似乎找不到解决方案。

如果有人能展示执行此宏的正确方法以便它解析为 Unicode 字符串文字,我将不胜感激。

更新:

#define STRINGIFY_RETURN_WIDE(x)    case x:     return L#x ""

没有抛出 C2440 错误,但它仍然给我 C2308。

更新 2:

我正在使用 Microsoft Visual Studio 2013

最佳答案

您有两个主要选择:

#define STRINGIFY_RETURN_WIDE(x) case x: return L#x L""

这将连接两个 L"…" 字符串。另一种更简单的解决方案是不连接空字符串:

#define STRINGIFY_RETURN_WIDE(x) case x: return L#x

尚不清楚附加空字符串是否有任何好处。


作为Robert Prévostcomment 中注明,这不适用于 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);

有一个解决方法:

#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";
    }
}

在带有 GCC 6.2.0 的 Mac OS X 10.11.6 上检查。

关于c++ - 使用 Unicode 字符串文字 Stringify 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39403121/

相关文章:

c - scanf ("%d",a) 使用 "while"语法绕过 scanf

c - 简单的 libnotify "hello world"程序无法在 Ubuntu 20.04 上编译并出现链接器错误

c++ - 我可以使用插入函数将值插入指针 vector 吗?

c++ - 有人可以向我解释这是未定义的行为吗?

mysql - snprintf 截断最后一个符号

objective-c - 有人可以解释这个宏吗?

c++ - 宏中的 typedef 字符

c++ - C/C++ 中可中断的命名范围

c++ - 为什么最初未定义长度的静态数组不会导致 C++ 中的编译错误?

C++ 访问定义宏数据