C ++在编译时将字符串文字转换为多字符文字

时间:2015-06-19 19:05:41

标签: c++ string character metaprogramming string-literals

基本上,如果我有这个字符串:

"abcd"

我想最终得到相当于:

'abcd'
编译时

。我尝试过使用宏,预处理器魔术和Microsoft的charize运算符(#@),但它们都没有正常工作。最终的结果应该让我做这样的事情:

template <long N> struct some_type {};
long whatever = STR_TO_MULTI_CHAR_LITERAL("abcd");
some_type<whatever> xyz;

2 个答案:

答案 0 :(得分:1)

让我们假设我们现在可以忘记大/小端,你可以使用constexpr union喜欢

union dirty_hack {
    long l;
    char[4] chars;
};

如果我们需要考虑endian,它会变得更复杂。 long的大小也可以是8,而不是4。

另一个想法是,如果long为32位,则在C ++ 11中支持char32_t char4b = U'\UAABBFFFF'。但是,您需要找出从A45的地图(A的十六进制值)。然后将char4b投射到long

答案 1 :(得分:1)

如果您可以在C ++ 11模式(或更高版本)中编译,那么您可以在常量表达式时间内索引字符串文字:

#define STR_TO_MULTI_CHAR_LITERAL(s)                 \
    (sizeof(s) == 5                                  \
        ? s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3] \
        : throw "wrong length")
some_type<STR_TO_MULTI_CHAR_LITERAL("abcd")> xyz;

也就是说,如果您被允许使用C ++ 11模式,您也应该能够使用constexpr

constexpr std::int32_t strToMultiCharLiteral(char const (&s)[5]) {
    return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
}
some_type<strToMultiCharLiteral("abcd")> xyz;

您甚至可以编写用户定义的字符串文字:

constexpr std::int32_t operator""_multiCharLiteral(char const *s, std::size_t len)
{
  return len == 4 ? s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]
    : throw "wrong length";
}
some_type<"abcd"_multiCharLiteral> xyz;