Я являюсь автором P0482 и P1423 char8_t
.
Кроме того, это беспорядок.
Я полностью согласен. SG16 работает над улучшением всех вещей, связанных с Юникодом и текстом, но мы должны начать с уровня земли, так что это займет некоторое время.
Если вы еще не видели Тем не менее, репозиторий, связанный ниже, предоставляет некоторые утилиты для написания кода, который будет работать на C ++ 17 и C ++ 20.
C ++, любые стандарты, не имеют средств для указания того, что исходный код имеет заданную кодировку текста (что-то вроде Python 'encoding: ... метаданные), и какие стандарты он может быть скомпилирован в (как, скажем, #! / bin / env g ++ -std = c ++ 14).
Это правильно, но не без прецедента. Компилятор IBM xl C поддерживает директиву #pragma filetag
, которая действует аналогично объявлению кодировки Python. Я начал на бумаге, исследуя это место, и надеялся представить его для пражской встречи, но не успел завершить его вовремя. Я ожидаю представить его на совещание в Варне (в июне).
Вплоть до C ++ 11 не было никакого способа указать, что у любого заданного строкового литерала будет заданная кодировка - компилятор был свободен для преобразования строкового литерала UTF8 в, скажем, UTF16 или даже EBCDI C, если он того пожелал.
Правильно, и это технически остается верным для строковых литералов char16_t
и char32_t
до C ++ 20 и принятия P1041 . Обратите внимание, что повторного анализа не происходит. На этапе перевода 1 содержимое исходного кода преобразуется во внутреннюю кодировку компилятора, а затем на этапе перевода 5 символьные и строковые литералы преобразуются в кодировку соответствующего набора символов выполнения. .
C ++ 11 вводит u16 «текст» и u32 «текст» и связанные типы символов для создания текста в кодировке UTF16 и UTF32, но не предоставляет строковых или потоковых средств для работы с ними, поэтому они в основном бесполезны.
Правильно. P1629 - одно из наиболее значительных изменений, которые мы надеемся завершить в C ++ 23. Цель состоит в том, чтобы предоставить кодировщики текста, декодеры и транскодеры, которые облегчают работу с текстом на уровне кодовой единицы и кодовой точки. Мы также обеспечили бы поддержку перечисления графемных кластеров.
C ++ 11 также вводит u8 «текст» для создания строки в кодировке UTF8 ... но даже не вводит ни правильный тип UTF8 char или строковый тип (это то, что char8_t предназначен для C ++ 20?), так что он даже полезнее, чем выше.
Правильно. Целью C ++ 20 было: 1) включить разграничение "text"
и u8"text"
в системе типов, 2) включить разделение зависимого от локали и текста UTF-8 (с применением системы типов), 3) обеспечить использование тип без знака для кодовых единиц UTF-8 и 4) избегать штрафа за наложение типа char
. Это было все, что мы успели сделать для C ++ 20 (стандартизация не быстрый процесс).
Из-за всего этого, когда наконец-то вводится char8_t, он убивает много кода, который должен был быть допустимым, и до сих пор некоторые из искомых исправлений включают в себя полное отключение поведения char8_t.
Правильно, char8_t
было предложено как критическое изменение; что-то не следует воспринимать легкомысленно. В этом случае это было сочтено приемлемым, потому что 1) при поиске кода было обнаружено незначительное использование u8
символьных и строковых литералов, 2) варианты решения проблем обратной совместимости, которые обсуждались в P1423, были сочтены адекватными, и 3) предложение о неразрывности добавил бы в язык долгосрочный багаж за небольшую выгоду.
Даже в этом случае нет легкодоступного инструментария (как в: не тот же интерфейс уровня дерьма, что и) для проверки, преобразования (в пределах того же самого строка) или конвертировать (копирование через строковые типы) текстовые кодировки в C ++. Кажется, даже codecvt пропал.
Правильно. Мы будем работать над улучшением этой ситуации, но это займет время. codecvt
не было отброшено (пока); заголовок <codecvt>
и различные UTF-преобразователи устарели в C ++ 17. std::codecvt
страдает от проблем с производительностью и удобством использования, поэтому мы не можем продолжать развивать это. Мы считаем, что P1629 - превосходное направление.
Почему C ++ не добавил char8_t в надлежащее время, когда был введен u8 «текст», или иным образом задержал введение u8?
Я спросил одного из членов комитета C ++, который участвовал в этой первоначальной работе. Он сказал мне, что спросил у людей, работающих над Unicode, нужно ли добавить новый тип, и ответил: «Э, нам это не нужно».
В качестве альтернативы, почему Не является ли еще один неразрывный префикс, такой как текст «c8», введенный с char8_t в C ++ 20 вместо внесения широкомасштабных изменений? Я думал, что TPTB ненавидит ломать изменения, даже больше того, что буквально ломает простейший возможный случай: префикс cout << hello world. </p>
Был рассмотрен другой префикс, и в какой-то момент я кратко одобрил этот подход , Однако, как упоминалось ранее, это оставило бы у нас два способа написания литералов UTF-8 и связанного исторического багажа. В долгосрочной перспективе считалось, что критическое изменение, если у нас есть разумные средства для смягчения поломки, дает больше преимуществ.
Что касается этого простого контрольного примера, уделите минуту, чтобы подумать о том, что этот код должен сделать. Затем go прочитайте это: Что такое символ форматирования printf () для char8_t *? .
Является ли char8_t функционально (ближе к) псевдонимом неподписанного символа или чар?
char8_t
преднамеренно и явно не является псевдонимом (поскольку это имеет негативные последствия для производительности), но задано для того же базового представления, что и unsigned char
. Причина, по которой unsigned char
превышает char
, состоит в том, чтобы избегать выражений типа u8'\x80' < 0
, когда-либо имеющих значение true (что может или не может иметь место в случае char
сегодня).
Если первое работает ли, например: typedef std :: basic_string u8string жизнеспособной стратегии эмуляции? Доступны ли реализации бэкпорта / ссылки, на которые можно посмотреть, прежде чем писать мою собственную?
Я не буду комментировать, является ли этот подход хорошей идеей или нет, но это было сделано раньше. Например, EASTL имеет такой typedef (Этот проект также предоставляет определение char8_t
, если собственный тип недоступен )
Что ближе всего мы имеем в C ++ 17 или ниже для маркировки текста как (предназначенного для) UTF-8 только для хранения ?
Я не думаю, что там один правильный ответ на этот вопрос. Я видел, как проекты используют unsigned char
или предоставляют char8_t
подобный тип через класс.
Что касается вашего псевдокода, некоторые изменения в коде в ранее упомянутом char8_t-remediation хранилище для предоставления unsigned char
типов вместо char
должно разрешить работу кода, подобного следующему. См. определения пользовательских литералов _as_char
и U8
макроса .
typedef std::basic_string<unsigned char> u8string;
u8string u8s(U8("text"));