2015-06-19 38 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