简体   繁体   English

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

[英]C++ convert string literal to multi-character literal at compile time

Basically, if I have this string: 基本上,如果我有这个字符串:

"abcd"

I want to end up with the equivalent of: 我想最终得到相当于:

'abcd'

at compile time . 在编译时 I have tried using macros, preprocessor magic, and Microsoft's charize operator ( #@ ), but none of them work correctly. 我曾尝试使用宏,预处理器魔术和Microsoft的charize运算符( #@ ),但它们都没有正常工作。 The end result should allow me to do something like this: 最终结果应该允许我做这样的事情:

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

Let us assume that we can forget about big/little endian for now, you could use a constexpr union like 让我们假设我们现在可以忘记大/小端,你可以使用constexpr union

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

If we need to consider endian, it becomes more complex. 如果我们需要考虑endian,它会变得更复杂。 Also size of long could be 8, not 4. long也可以是8,而不是4。

Another thought, if long is 32bit, char32_t char4b = U'\\UAABBFFFF' is supported in C++11. 另一个想法,如果long是32位,则C ++ 11支持char32_t char4b = U'\\UAABBFFFF' But then you need figure out the map from A to 45 (hex value of A ). 不过,你需要从地图上找出A45 (十六进制值A )。 Then cast char4b to long . 然后将char4blong

If you can compile in C++11 mode (or above), then you're allowed to index into string literals at constant-expression time: 如果您可以在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;

That said, if you're allowed to use C++11 mode you should be able to use constexpr as well: 也就是说,如果您被允许使用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;

You can even write a user-defined string literal: 您甚至可以编写用户定义的字符串文字:

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;

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

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