C ++ converts string literal to multi-character literal at compile time

Basically, if I have this line:

"abcd"

      

I want to get the equivalent:

'abcd'

      

at compile time. I've tried using macros, preprocessor magic, and Microsoft's charize ( #@

) operator , but none of them work correctly. 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;

      

+3


source to share


2 answers


Suppose now we can forget about big / small endian, you can use constexpr

union

like

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

      



If we need to consider endian, it becomes more complex. Also, the size long

can be 8, not 4.

Another thought if long

32bit is char32_t char4b = U'\UAABBFFFF'

supported in C ++ 11. But then you need to figure out the map from A

to 45

(hex value A

). Then we discard char4b

in long

.

+1


source


If you can compile in C ++ 11 (or higher) mode, you will be allowed to index into string literals with a constant expression:

#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 are allowed to use C ++ 11 mode, you should also be able to use 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 custom 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;

      

+1


source







All Articles