由于我使用的域的限制,我需要将字符串文字都定义为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++标准在编译时实现相同的结果?预先感谢您的帮助。

最佳答案

如果只能将字符串文字限制为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

它对于C++ 11应该可行,但是需要大量样板代码。

这是C++14 version

10-04 14:43
查看更多