char8_t
, как char
, signed char
и unsigned char
, имеет размер 1 байт. На большинстве платформ (но не на всех!) Это означает, что это 8-битный тип, способный содержать только 256 дискретных значений. Unicode 12.1 определяет 137 994 символа. Очевидно, что все они не могут вписаться в одно char8_t
значение!
Типы "символов" C и C ++, к сожалению, плохо названы. Если бы мы разрабатывали новый язык с современной терминологией, мы бы назвали их некоторыми вариациями code_unit
, поскольку они лучше отражают то, как они фактически используются. char32_t
является единственным типом символов, который в настоящее время гарантированно может содержать значение кодовой точки для каждого символа в соответствующем наборе символов (стандарты C и C ++ утверждают, что wchar_t
тоже может, но это противоречит существующей практике ).
Глядя на ваш пример, À - это U + 00C0 {ПИСЬМО ЛАТИНСКОГО КАПИТА A С МОЛОДОЙ} (или на самом деле это U + 0041 {ПИСЬМО ЛАТИНСКОГО КАПИТАЛА A}, за которым следует ̀ U + 0300 {КОМБИНИРОВАННАЯ МОЩНОСТЬ ACCENT}? Юникод так сложен). Кодировка UTF-8 U + 00C0 составляет 0xC3 0x80. Какое значение должно содержать french_letter_A_1
? Он не может содержать оба значения кодовых единиц. И если значение должно быть кодовой точкой, то мы либо в ситуации, когда (переносимо) может поддерживаться только 256 символов, либо, что еще хуже, иногда значения char8_t
являются кодовыми точками, а иногда - кодовыми единицами.
Реальность такова, что литералы символов C и C ++ ограничены всего несколькими символами, чем в исходном наборе символов basi c . Этого достаточно, если вы пишете только на Engli sh -приложении. Но для современных приложений литералы символов имеют ограниченное использование.
Как уже говорил Николь, работа с большинством символов вне исходного набора символов c требует реальной обработки текста в строках. К сожалению, стандарты C и C ++ здесь не сильно помогают. Это то, что SG16 работает над улучшением.