C++11 理解 (十八) 之 字串字面值
標準C++提供了兩種字串字面值。第一種,包含有雙引號,產生以空字元結尾的const char陣列。第二種有著前標L,產生以空字元結尾的const wchar_t陣列,其中wchar_t代表寬字元。對於Unicode編碼的支援尚付闕如。
為了加強C++編譯器對Unicode的支援,類別char的定義被修改為其大小至少能夠儲存UTF-8的8位編碼,並且能夠容納編譯器的基本字符集的任何成員。
C++11 將支援三種Unicode編碼方式:UTF-8,UTF-16,和UTF-32。除了上述char定義的變更, C++11將增加兩種新的字元類別:char16_t和char32_t。它們各自被設計用來儲存UTF-16 以及UTF-32的字元。
以下展示如何產生使用這些編碼的字串字面值:
u8"I'm a UTF-8 string." u"This is a UTF-16 string." U"This is a UTF-32 string."
第一個字串的類別是通常的const char[]
;第二個字串的類別是const char16_t[]
;第三個字串的類別是const
char32_t[]
。
當建立Unicode字串字面值時,可以直接在字串內插入Unicode codepoints。C++11提供了以下的語法:
u8"This is a Unicode Character: \u2018." u"This is a bigger Unicode Character: \u2018." U"This is a Unicode Character: \u2018."
在'\u'之後的是16個位元的十六進位制數值;它不需要'0x'的前標。識別字'\u'代表了一個16位的Unicode codepoint;如果要輸入32位的codepoint,使用'\U'和32個位元的十六進位制數值。只有有效的Unicode codepoints能夠被輸入。舉例而言,codepoints在範圍U+D800—U+DFFF之間是被禁止的,它們被保留給UTF-16編碼的surrogate pairs。
有時候避免手動將字串換碼也是很有用的,特別是在使用XML檔案或是一些指令碼語言的字面值的時候。 C++11將提供raw(未加工的)字串字面值:
R"(The String Data \ Stuff " )" R"delimiter(The String Data \ Stuff " )delimiter"
在第一個例子中,任何包含在(
)
括號(標準已經從[]
改為()
)當中的都是字串的一部分。其中"
和\
字元不需要經過跳脫(escaped)。在第二個例子中,"delimiter(
開始字串,只有在遇到)delimiter"
才代表退出。其中delimiter
可以是任意的字串,能夠允許使用者在未加工的字串字面值中使用)
字元。
未加工的字串字面值能夠和寬字面值或是Unicode字面值結合:
u8R"XXX(I'm a "raw UTF-8" string.)XXX" uR"*@(This is a "raw UTF-16" string.)*@" UR"(This is a "raw UTF-32" string.)"
使用者自定義的字面值:
標準C++提供了數種字面值。字元"12.5"是能夠被編譯器解釋為數值12.5的double類別字面值。然而,加上"f"的後置,像是"12.5f",則會產生數值為12.5的float類別字面值。在C++規範中字面值的後置是固定的,而且C++程式碼並不允許創立新的字面後置。
C++11 開放使用者定義新的字面修飾符(literal modifier),利用自定義的修飾符完成由字面值建構物件。
字面值轉換可以區分為兩個階段:轉換前與轉換後 (raw 與 cooked)。 轉換前的字面值指特定字串行,而轉換後的字面值則代表另一種類別。 如字面值1234,轉換前的字面值代表 '1', '2', '3', '4' 的字串行; 而轉換後,字面值代表整數值1234。 另外,字面值0xA轉換前是序列'0', 'x', 'A';轉換後代表整數值 10。