简体   繁体   English

将字符串文字常量定义为 char const* 和 wchar const*

[英]Defining string literal constants once both as char const* and wchar const*

Due to the constraints of the domain I'm working with, I need to define string literals both as char const* and wchar const*, for example:由于我正在使用的域的限制,我需要将字符串文字定义为 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";
...

I have lots of constants and I'd like to avoid to define twice the same actual name of the variable (which could lead to some typo, hence unmatching names), so I've used some macro like this:我有很多常量,我想避免定义两次相同的变量实际名称(这可能导致一些拼写错误,因此名称不匹配),所以我使用了一些这样的宏:

#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)
...

This works but, if possible, I'd like to get rid of the macro stuff;这可行,但如果可能的话,我想摆脱宏的东西; so my question is: is it possible to achieve the same result at compile-time using plain C++ standard without macros?所以我的问题是:是否可以在编译时使用没有宏的普通 C++ 标准来获得相同的结果? Thank you in advance for your help.预先感谢您的帮助。

If you can limit string literal to ASCII characters only there is simple solution without use of macros (in version for C++17):如果您只能将字符串文字限制为 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)" };

Demo演示

It should be doable for C++11, but lots of boiler plate code is needed. C++11 应该是可行的,但是需要大量的样板代码。

Here is C++14 version .这是C++14 版本

I would do this like that:我会这样做:

#include <string_view>

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

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

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM