2015-06-19 71 views
3

基本上,如果我有这个字符串:C++转换字符串文本多字符文字在编译时

"abcd" 

我想与相当于落得:

'abcd' 

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

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

*“Microsoft的charize运算符”*所以你使用MSVC编译器?哪个版本? VS2015/MSVC 19支持constexpr功能.. – dyp

+0

@dyp'clang -fms-extensions',虽然结果应该在没有* constexpr的MSVC下工作。 – refi64

+0

可能会将字符串分解为一系列字符([通过宏](http://web.archive.org/web/20130930081424/http://cpp-next.com/archive/2012/10/) using-strings-in-c-template-metaprograms /)),然后从该字符序列重建一个数字。 – dyp

回答

1

让我们假设,我们可以了解大/小尾数忘了现在,你可以使用一个constexprunion

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

如果我们需要考虑endian,它变得更加复杂。还的long尺寸可以是8,而不是4。

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

+0

在编译时输入双字符很可能不起作用。在Standardese中,在C++中禁止使用联合打字,并且在常量表达式中禁止使用“reinterpret_cast”。(在编译时为什么禁止类型剔除有一个更基本的原因,但我一直忘记它。)请参阅http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1188 – dyp

+0

@dyp,你是对的,在C++中可能不可行。也许只是使用C的那部分。 –

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; 
+1

不错的想法,但OP说(在评论中),这个必须在没有'constexpr'的MSVC下运行。不幸的是,VS2013拒绝''abcd“[0]'作为常量表达式:( – dyp