【问题标题】:C++ convert string literal to multi-character literal at compile timeC++ 在编译时将字符串文字转换为多字符文字
【发布时间】:2015-06-19 19:05:41
【问题描述】:

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

"abcd"

我想最终得到相当于:

'abcd'

在编译时。我尝试过使用宏、预处理器魔法和 Microsoft 的 charize 运算符 (#@),但它们都不能正常工作。最终结果应该允许我做这样的事情:

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

【问题讨论】:

  • "Microsoft's charize operator" 那么您使用的是 MSVC 编译器吗?哪个版本? VS2015 / MSVC 19 支持 constexpr 函数..
  • @dyp clang -fms-extensions,虽然结果应该在 MSVC 下工作没有 constexpr。
  • 有可能将字符串分解为字符序列 (via macros),然后从该字符序列重建一个数字。
  • 在您的情况下是否可以添加包含字符串的全局/静态局部变量的定义? const char str[] = "abcd"; 之类的东西——这可以用来将字符串传递给元函数;不允许直接传递字符串文字。
  • @dyp 但是我可以索引它吗?

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


【解决方案1】:

假设我们现在可以忘记大/小端,您可以使用 constexpr union 之类的

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

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

另一个想法,如果 long 是 32 位的,那么 C++11 支持 char32_t char4b = U'\UAABBFFFF'。但是你需要找出从A 到45 的映射(A 的十六进制值)。然后将char4b 转换为long。

【讨论】:

  • 编译时的类型双关语很可能不起作用。在 Standardese 中,C++ 中禁止通过联合进行类型双关语,并且在常量表达式中也禁止使用 reinterpret_cast。 (在编译时禁止类型双关语还有一个更根本的原因,但我一直忘记它..)见open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1188
  • @dyp,你是对的,这在 C++ 中可能不可行。也许只是使用 C 作为那部分。
【解决方案2】:

如果您可以在 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;

【讨论】:

  • 好主意,但 OP 说(在 cmets 中)这必须在没有 constexpr 的 MSVC 下运行。不幸的是,VS2013 拒绝 "abcd"[0] 作为常量表达式 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 2011-10-06
  • 2015-10-19
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多