Я делал немного чтения по теме Unicode - в частности, поддержка UTF-8 - (non) в С++ 11, и я надеялся, что гуру в Qaru могут успокоить меня, что мой понимание правильное, или указать, где я неправильно понял или пропустил что-то, если это так.
Краткий обзор
Во-первых, хорошо: вы можете определить литералы UTF-8, UTF-16 и UCS-4 в исходном коде. Кроме того, заголовок <locale>
содержит несколько реализаций std::codecvt
, которые могут конвертировать между любыми UTF-8, UTF-16, UCS-4 и многобайтовой кодировкой платформы (хотя API, кажется, мягко, меньше, чем простой). Эти реализации codecvt
могут быть imbue()
'd в потоках, чтобы вы могли выполнять преобразование при чтении или записи файла (или другого потока).
[ EDIT:. В комментариях Кубби указывает, что я не упоминал заголовок <codecvt>
, который предоставляет реализации std::codecvt
, которые не зависят от локали. Кроме того, функции std::wstring_convert
и wbuffer_convert
могут использовать эти codecvt
для прямого преобразования строк и буферов, не полагаясь на потоки.]
С++ 11 также включает заголовок C99/C11 <uchar.h>
, который содержит функции для преобразования отдельных символов из многобайтовой кодировки платформы (которая может быть или не быть UTF-8) в UCS-2 и UCS-4.
Однако, что о его масштабах. Хотя вы можете, конечно, хранить текст UTF-8 в std::string
, нет никаких способов, которые я могу увидеть, чтобы сделать что-нибудь действительно полезное с ним. Например, помимо определения литерала в вашем коде, вы не можете проверить массив байтов как содержащий допустимый UTF-8, вы не можете узнать длину (то есть число символов Юникода для некоторого определения "символ", ) UTF-8-содержащего std::string
, и вы не можете перебирать по std::string
любым способом, кроме байта.
Аналогично, даже добавление С++ 11 std::u16string
на самом деле не поддерживает UTF-16, а только более старый UCS-2 - он не поддерживает суррогатные пары, оставляя вас только BMP.
Наблюдения
Учитывая, что UTF-8 является стандартным способом обработки Unicode почти для каждой производной от Unix системы (включая Mac OS X и * Linux) и в значительной степени стал стандартом де-факто на Интернет, отсутствие поддержки в современном С++ кажется довольно серьезным упущением. Даже в Windows факт, что новый std::u16string
не поддерживает UTF-16, кажется несколько прискорбным.
* Как указано в комментариях и сделана ясная здесь, части Mac OS, полученные из BSD, используют UTF-8, а Cocoa использует UTF -16.суб >
Вопросы
Если вам это удалось, спасибо! Просто несколько быстрых вопросов, так как это переполнение стека в конце концов...
-
Является ли приведенный выше анализ правильным, или существуют ли какие-либо другие поддерживающие Unicode средства, которые мне не хватает?
-
Комитет по стандартам проделал фантастическую работу за последние пару лет, продвигая вперед C++ вперед быстрыми темпами. Они все умные люди, и я предполагаю, что они хорошо знают вышеупомянутые недостатки. Есть ли какая-то известная причина, по которой поддержка Unicode остается такой плохой в С++?
-
Идет ли кто-нибудь о любых предложениях по исправлению ситуации? Быстрый поиск на isocpp.org, похоже, ничего не показывал.
EDIT: Спасибо всем за ваши ответы. Должен признаться, что я нахожу их немного обескураживающими - похоже, статус-кво вряд ли изменится в ближайшем будущем. Если есть консенсус среди cognoscenti, кажется, что полная поддержка Unicode слишком сложна и что любое решение должно переопределить большинство ICU, чтобы считаться полезным.
Я лично не согласен с этим; Я думаю, что есть ценная средняя почва. Например, алгоритмы валидации и нормализации для UTF-8 и UTF-16 хорошо определены консорциумом Unicode и могут быть предоставлены стандартной библиотекой в виде бесплатных функций, например, в пространстве имен std::unicode
. Только они будут полезны для программ на С++, которые должны взаимодействовать с библиотеками, ожидающими ввода Unicode. Но, основываясь на ответе ниже (оттенок, надо сказать, с намеком на горечь), кажется, что предложение Puppy только для такого рода ограниченной функциональности было плохо воспринято.