将字符串文字常量一次定义为 char const* 和 wchar const*
Defining string literal constants once both as char const* and wchar const*
由于我正在使用的域的限制,我需要将字符串文字定义为 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++ 标准获得相同的结果?预先感谢您的帮助。
我会这样做:
#include <string_view>
struct DoubleStringLiteral {
std::string_view str;
std::wstring_view wstr;
};
#define DOUBLE_LITERAL(name, value) \
constexpr DoubleStringLiteral name { \
value, \
L ## value \
}
如果您只能将字符串文字限制为 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 version。
由于我正在使用的域的限制,我需要将字符串文字定义为 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++ 标准获得相同的结果?预先感谢您的帮助。
我会这样做:
#include <string_view>
struct DoubleStringLiteral {
std::string_view str;
std::wstring_view wstr;
};
#define DOUBLE_LITERAL(name, value) \
constexpr DoubleStringLiteral name { \
value, \
L ## value \
}
如果您只能将字符串文字限制为 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 version。