Строковые литералы Unicode

В C++11 представлен новый набор префиксов строковых литералов (и даже разрешены пользовательские суффиксы). Кроме того, вы можете напрямую использовать escape-последовательности Unicode для кодирования определенного символа, не беспокоясь о кодировании.

const char16_t* s16 = u"\u00DA";
const char32_t* s32 = U"\u00DA";

Но могу ли я также использовать escape-последовательности Unicode в строковых литералах wchar_t? Это выглядело бы дефектом, если бы это было невозможно.

const wchar_t* sw = L"\u00DA";

Целочисленное значение sw[0], конечно, будет зависеть от того, что такое wchar_t на конкретной платформе, но для всех остальных эффектов это должно быть переносимым, не так ли?


person rubenvb    schedule 03.10.2011    source источник
comment
Я считаю, что значение sw[0] зависит от того, что wchar_t есть на конкретной платформе, только в той степени, в какой размер wchar_t. т.е. \u00DA всегда должен приводить к некоторой кодировке Unicode (UTF-8, UTF-16, UTF-32) U+00DA, даже если это не обычная кодировка платформы для этого типа.   -  person bames53    schedule 17.10.2011
comment
На самом деле вышесказанное неверно. Предполагается, что реализация обрабатывает универсальные имена символов так же, как и буквальные символы. Таким образом, если реализация переводит символы строкового литерала в набор символов выполнения, она должна делать это и с UCN. Кодировка UTF гарантируется только в том случае, если UCN находится внутри литерала Unicode (например, u8Ú).   -  person bames53    schedule 19.10.2011


Ответы (1)


Это будет работать, но может не иметь желаемой семантики. \u00DA будет расширяться до такого количества целевых символов, которое необходимо для кодировки UTF8/16/32, в зависимости от размера wchar_t, но имейте в виду, что широкие строки не имеют какой-либо документированной, гарантированной семантики кодирования — они просто «системные кодировка", не пытаясь сказать, что это такое, или требовать от пользователя знания, что это такое.

Так что лучше не смешивать. Используйте любой из двух, но не оба:

  1. специфичные для системы: char*/"", wchar_t*/L"", \x-литералы, mbstowcs/wcstombs

  2. Юникод: char*/u8"", char16_t*/u"", char32_t*/U"", \u/\U литералы.

(Вот некоторые related мои вопросы по этому вопросу.)

person Kerrek SB    schedule 03.10.2011
comment
Для получения полной информации об истории этого вопроса, этот тест libc++ не работает в Windows на строке \x00DA. Интересно, могу ли я заменить это на \u00DA и заставить его работать для всех wchar_t, которые достаточно велики (т.е. 16 или 32-битные) - person rubenvb; 03.10.2011
comment
/u для utf16, /u для utf32, что для utf8? (и я не имею в виду префикс строки, это u8, я имею в виду шестнадцатеричный префикс внутри строки) - person MarcusJ; 07.04.2018
comment
Вы имеете в виду \, а не /? Это две разные вещи. Также обратите внимание, что я никогда не говорил, что \u для UTF-16. Экранированное значение всегда представляет собой абстрактную кодовую точку (= число); просто \U принимает 32-битное число, а \u принимает 16-битное число. Я не совсем уверен, какой может быть правильная версия вашего вопроса, возможно, что-то вроде ссылки на 8-битную кодовую точку, то есть кодовые точки в диапазоне [0, 256)? Я предполагаю, что это могло бы существовать, но имело бы чрезвычайно ограниченное значение, поскольку большинство этих кодовых точек легко доступны через ASCII и не нуждаются в экранировании. - person Kerrek SB; 07.04.2018