将字符串字面常量同时定义为 char const* 和 wchar const* 的方法。

7

由于我所使用的领域的限制,我需要将字符串字面量定义为char const*和wchar const*两种类型,例如:

constexpr auto C_VAR_NAME_1 = "MY_VAR_NAME_1";
constexpr auto C_VAR_NAME_2 = "MY_VAR_NAME_2";
...

constexpr auto W_VAR_NAME_1 = L"MY_VAR_NAME_1";
constexpr auto W_VAR_NAME_2 = L"MY_VAR_NAME_2";
...

我有许多常量,希望避免重复定义相同的变量名称(可能会导致一些拼写错误,从而导致名称不匹配),因此我使用了以下类似宏的方法:

#define WTEXT_IMPL(name) L##name
#define WTEXT(name)      WTEXT_IMPL(name)

#define MACRO_VAR_NAME_1 "MY_VAR_NAME_1"
#define MACRO_VAR_NAME_2 "MY_VAR_NAME_2"
...

constexpr auto C_VAR_NAME_1 = MACRO_VAR_NAME_1;
constexpr auto C_VAR_NAME_2 = MACRO_VAR_NAME_2;
...
constexpr auto W_VAR_NAME_1 = WTEXT(MACRO_VAR_NAME_1)
constexpr auto W_VAR_NAME_2 = WTEXT(MACRO_VAR_NAME_2)
...

这个代码可以运行,但如果可能的话,我想摆脱宏;我的问题是:是否有可能在不使用宏的情况下,在编译时使用纯C++标准实现相同的结果?非常感谢您的帮助。

2个回答

3
如果您可以仅将字符串文字限制为ASCII字符,那么在不使用宏的情况下(在C++17版本中)有一个简单的解决方案:
template<std::size_t N>
struct DoubleStringLiteral {
    constexpr DoubleStringLiteral(const char(&s)[N])
    {
        for (size_t i=0; i<N; ++i) {
            if (s[i] < 0) throw std::invalid_argument("None ASCII character are not supported!");
            str[i] = s[i];
            wstr[i] = static_cast<wchar_t>(s[i]);
        }
    }

    constexpr std::string_view view() const
    {
        return { str };
    }

    constexpr std::string_view wview() const
    {
        return { wstr };
    }

    char str[N];
    wchar_t wstr[N];
};

constexpr DoubleStringLiteral a{ "Demo!" };
constexpr DoubleStringLiteral b{ R"(Raw!
str
sample)" };

演示

对于C++11来说,这是可以实现的,但需要大量的样板代码。

这里是C++14版本


太棒了!我认为这个解决方案绝对解决了我的问题(是的,我只需要ASCII字符);非常感谢你! - Stefano Bellotti

1
我会这样做:
#include <string_view>

struct DoubleStringLiteral {
    std::string_view str;
    std::wstring_view wstr;
};

#define DOUBLE_LITERAL(name, value) \
    constexpr DoubleStringLiteral name { \
        value, \
        L ## value \
    }

演示


仍然使用宏,只是最小化重复。 - Tanveer Badar
see other answer. - Marek R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接