1. 程式人生 > >C++11 理解 (十八) 之 字串字面值

C++11 理解 (十八) 之 字串字面值

標準C++提供了兩種字串字面值。第一種,包含有雙引號,產生以空字元結尾的const char陣列。第二種有著前標L,產生以空字元結尾的const wchar_t陣列,其中wchar_t代表寬字元。對於Unicode編碼的支援尚付闕如。

為了加強C++編譯器對Unicode的支援,類別char的定義被修改為其大小至少能夠儲存UTF-8的8位編碼,並且能夠容納編譯器的基本字符集的任何成員。

C++11 將支援三種Unicode編碼方式:UTF-8UTF-16,和UTF-32。除了上述char定義的變更, C++11將增加兩種新的字元類別:char16_tchar32_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。