Подтвердить что ты не робот

Unicode в С++ 11

Я делал немного чтения по теме 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 только для такого рода ограниченной функциональности было плохо воспринято.

4b9b3361

Ответ 1

Правильно ли указан вышеприведенный анализ

Посмотрим.

вы не можете проверить массив байтов как содержащий действительный UTF-8

Неправильно. std::codecvt_utf8<char32_t>::length(start, end, max_lenght) возвращает количество действительных байтов в массиве.

вы не можете узнать длину

Частично правильно. Можно преобразовать в char32_t и узнать длину результата. Нет простого способа узнать длину без фактического преобразования (но см. Ниже). Я должен сказать, что необходимость подсчета символов (в любом смысле) возникает довольно редко.

вы не можете перебирать по std::string любым способом, кроме байта по байту

Неправильно. std::codecvt_utf8<char32_t>::length(start, end, 1) дает вам возможность перебирать символы UTF-8 (Unicode code units) и, конечно, определять их число (это не "простой" способ подсчета количества символов, но это способ).

не поддерживает UTF-16

Неправильно. Можно преобразовать в UTF-16 и из него с помощью, например, std::codecvt_utf8_utf16<char16_t>. Результатом преобразования в UTF-16 является, ну, UTF-16. Это не ограничивается BMP.

Демо, иллюстрирующая эти точки.

Если я пропустил какой-то другой "вы не можете", пожалуйста, укажите его, и я рассмотрю его.

Важное добавление. Эти средства устарели в С++ 17. Вероятно, это означает, что они исчезнут в какой-то будущей версии С++. Используйте их на свой страх и риск. Все эти вещи, перечисленные в оригинальном вопросе, теперь нельзя (безопасно) сделать снова, используя только стандартную библиотеку.

Ответ 2

Является ли приведенный выше анализ правильным, или есть ли другие Поддержка Unicode объектов отсутствует?

Вам также не хватает полного отказа от литералов UTF-8. У них нет четкого типа для узкосимвольных литералов, которые могут иметь кодировку с абсолютно несвязанными (например, кодовыми страницами). Таким образом, они не только не добавили каких-либо серьезных новых возможностей на С++ 11, они сломали то, что мало было, потому что теперь вы даже не можете предположить, что char* используется в узкоколонном кодировании для вашей платформы, если UTF-8 это кодировка узкой строки. Итак, новая функция здесь: "Мы полностью сломали строки на основе char на каждой платформе, где UTF-8 не является существующей узкой строковой кодировкой".

Комитет по стандартам проделал фантастическую работу в последние пару лет лет двигаясь вперед на C++ вперед. Они все умные люди и Я предполагаю, что они хорошо знают вышеупомянутые недостатки. Есть ли особая известная причина, по которой поддержка Unicode остается настолько С++?

Комитет просто, похоже, не дерьмо относится к Юникоду.

Кроме того, многие из алгоритмов поддержки Unicode - это просто алгоритмы. Это означает, что для обеспечения достойного интерфейса нам нужны диапазоны. И мы все знаем, что Комитет не может понять, чего они хотят w.r.t. диапазоны. Новая вещь Iterables от Эрика Ниблера может иметь шанс.

Вперед, кто-нибудь знает какие-либо предложения об исправлении ситуация? Быстрый поиск на isocpp.org, похоже, не выявил что-нибудь.

Был N3572, который я создал. Но когда я отправился в Бристоль и представил его, возникло множество проблем.

Во-первых, оказывается, что Комитет не утруждает себя обратной связью по предложениям, не связанным с комитетом, между встречами, в результате чего месяцы утраченной работы, когда вы повторяете проект, который им не нужен.

Во-вторых, оказывается, что он проголосовал тем, кто когда-либо блуждает в то время. Это означает, что если ваша бумага будет перенесена, у вас будет относительно случайная группа людей, которые могут или не могут ничего знать о предмете. Или действительно, что угодно.

В-третьих, по какой-то причине они, похоже, не рассматривают текущую ситуацию как серьезную проблему. Вы можете бесконечно обсуждать, как точно следует определять операции сравнения optional<T>, но иметь дело с пользовательским вводом? Кому это нужно?

В-четвертых, каждая статья нуждается в чемпионе, эффективно, чтобы представлять и поддерживать его. Учитывая предыдущие проблемы, а также тот факт, что я не мог позволить себе путешествовать на другие встречи, это, безусловно, не будет, не буду в будущем, если вы не захотите пожертвовать все мои командировочные расходы и заплатить зарплату наверху, и никто, похоже, не заботился об этом, чтобы приложить усилия.