Требует ли стандарт C ++ кодирования для wchar_t?

Вот некоторые выдержки из моей копии проекта стандарта N4140 2014 года

22.5 Стандартные аспекты преобразования кода [locale.stdcvt]

3 Для каждого из трех аспектов преобразования кодаcodecvt_utf8, codecvt_utf16, а такжеcodecvt_utf8_utf16:
(3.1) -Elem является типом широких символов, таким какwchar_t, char16_t, или жеchar32_t.

4 Для аспектаcodecvt_utf8:
(4.1) - Фасет должен преобразовывать между многобайтовыми последовательностями UTF-8 и UCS2 или UCS4 (в зависимости от размераElem) в рамках программы.

Одно из толкований этих двух параграфов состоит в том, чтоwchar_t должен быть закодирован как UCS2 или UCS4. Мне это не очень нравится, потому что, если это правда, у нас есть важное свойство языка, глубоко скрытое в описании библиотеки. Я пытался найти более прямое изложение этого свойства, но безрезультатно.

Другая интерпретация, котораяwchar_t кодирование не обязательно должно быть UCS2 или UCS4, и в реализациях, где это не так,codecvt_utf8 не будет работать дляwchar_t, Мне тоже не очень нравится эта интерпретация, потому что, если это правда, и ниchar ниwchar_t нативные кодировки - это Unicode, кажется, нет способа переносить между этими нативными кодировками и Unicode.

Какая из двух интерпретаций верна? Есть еще один, который я упустил из виду?

осветление Я не спрашиваю об общих мнениях о пригодностиwchar_t для разработки программного обеспечения, или свойстваwchar_t можно получить из другого места. Я заинтересованв этих двух конкретных пунктах стандарта. Я пытаюсь понять чтоэти конкретные пункты влечет за собой или не влечет за собой.

Пояснение 2, Если в 4.1 указано «фасет должен преобразовывать между многобайтовыми последовательностями UTF-8 и UCS2 или UCS4или любая другая кодировка, наложенная на wchar_t текущей глобальной локалью«Там не было бы никаких проблем. Это не так. Он говорит, что говорит. Кажется, что если кто-то используетstd::codecvt_utf8<wchar_t>один заканчивается кучейwchar_t кодируется как UCS2 или UCS4, независимо от текущей глобальной локали. (Нет способа указать локаль или какой-либо аспект преобразования символов дляcodecvt_utf8). Таким образом, вопрос можно перефразировать следующим образом: является ли результат преобразования непосредственно используемым с текущей глобальной локалью (и / или с любой возможной локалью) для вывода,wctype запросы и тд? Если нет, то что это можно использоватьза? (Если второе толкование выше верное, ответом будет «ничего»).

 Galik05 авг. 2016 г., 02:49
RE: Разъяснение 2.codecvt_utf8 специально только конвертирует юникод в юникод. Если вы хотите конвертировать текущую локаль в / из юникода, то я думаю, что вы можете использоватьСТД :: mbrtoc32 так далее...
 n.m.04 авг. 2016 г., 18:13
@NicolBolas да, я могу сказатьwchar_t x = 17, Это не имеет стандартного значения в области операций, которые имеют смысл для символов (в отличие от целых чисел).codecvt_utf8<wchar_t> иметь?
 n.m.05 авг. 2016 г., 02:27
@KerrekSB Хотите уточнить?
 Hans Passant04 авг. 2016 г., 17:03
Это не большая проблема. Они должны были исправить это снова с char16_t и char32_t в C ++ 11. Хотя он и не указывает кодировку, но кто бы не использовал его для utf16, а utf32 получит много грязных взглядов.
 David Haim04 авг. 2016 г., 16:56
wchar_t просто должен быть больше чемchar, вот и все..
 n.m.04 авг. 2016 г., 17:09
@Yakk Два абзаца из приведенного мною стандарта заставляют меня так думать. Можете ли вы интерпретировать их по-разному? Если да, то как? Это суть моего вопроса.
 Yakk - Adam Nevraumont04 авг. 2016 г., 17:14
@MSalters "зависит от текущей локали".std::iswalpha использует кодировку local, которая является просто глобальным состоянием.
 Richard Critten04 авг. 2016 г., 16:55
wchar_t не является переносимым. Например, в Unix это UTF-32, а в Windows - UTF-16 (не UCS2)
 n.m.04 авг. 2016 г., 17:39
@Galik Так ты намекаешь, что вторая интерпретация верна?
 Kerrek SB05 авг. 2016 г., 02:23
(Между прочим, половина всего этого кодового содержимого плохо определена и неосуществима.)
 n.m.04 авг. 2016 г., 17:39
@Yakk Неважно, где живет кодировка. Это может быть локаль, проникшая в поток или текущую глобальную локаль. Факт в том, что есть кодировка (возможно, несколько), и я спрашиваю, должны ли они / они все быть чем-то UCS.
 Kerrek SB05 авг. 2016 г., 02:32
@ n.m .: нет, подробности ускользают от меня, но я слышал, как несколько поставщиков библиотек говорили это неоднократно.
 n.m.05 авг. 2016 г., 02:55
@Galik да, я пишу о std :: mbrtoc32 в своем собственном ответе, но у меня все еще есть сомнения ...
 Galik04 авг. 2016 г., 17:32
В параграфах просто указывается, что должны делать преобразователи кода, они не диктуют, чтоwchar_t как правило, должны содержать.
 MSalters04 авг. 2016 г., 17:10
@Yakk: Что заставляет меня думатьwchar_t имеет фиксированную кодировку? Просто:std::iswalpha, Нет граней.
 Nicol Bolas04 авг. 2016 г., 18:00
"какая бы кодировка не накладывалась на wchar_t текущей глобальной локалью«Фасеты не навязывают кодировки для типов данных. Они навязывают кодировки дляоперации, Так что это заявление будетерунда.
 n.m.04 авг. 2016 г., 18:07
@NicolBolas Тип данных без набора операций бесполезен, поэтому любая кодировка, наложенная на операции, накладывается на сам тип данных.
 Kerrek SB04 авг. 2016 г., 17:00
кодирование это присвоение от числа к значению. Тип не имеет такой семантики.
 n.m.05 авг. 2016 г., 02:15
@KerrekSB В отрывке говорится, чтоwchar_t является используется для хранения значений набора символов выполнения. Процесс перевода программы делает это так, и он использует одно специальное отображение при этом. Можно картуwchar_t для других наборов, включая другие наборы символов, но это не имеет значения. Существует специальное отображение, и оно поставляется с реализацией.Я хочу, чтобы это специальное отображение было доступно из программ на C ++.
 Galik04 авг. 2016 г., 17:49
Я не верю, что любая интерпретация верна. Я думаю, это просто говорит, чтоcodecvt_utf8 использованияwchar_t и должен выбрать, какую кодировку производить в зависимости от размераwchar_t, Я не вижу ничего, что говорило бы оwchar_t сам.
 Yakk - Adam Nevraumont04 авг. 2016 г., 16:55
wchar_t является интегральным типом. Что заставляет вас думать, что у него фиксированная кодировка? Он может хранить номер7, и вы можете интерпретировать это как значение «пользователь нажал на левую кнопку». Где-то еще вы можете интерпретировать7 вwchar_T это означает «активировать пожарную сигнализацию», а в другом месте в нижнем регистреa, Интересная проблема заключается в том, что происходит, когда вы читаете из ввода и т.п., но это не кодировкаwchar_t но кодировка IO делает ... Грани описываюткаков результат кодирования при использовании этого аспекта в операции потоковой передачи...
 n.m.04 авг. 2016 г., 17:11
@RichardCritten Я не спрашиваю, как я или кто-либо другой должен использовать wchar_t, я спрашиваю, что говорит стандарт.
 Galik04 авг. 2016 г., 18:55
Это как сказатьstd::iota заполнит буфер конкретными значениями. Это не значит, что буферограниченный к этим ценностям и ничто иное не допустимо.
 Galik04 авг. 2016 г., 17:54
Единственное значение дляwchar_t (и другие типы символов), это должно бытьспособный содержащий либоUCS2 или жеUCS4 в зависимости от его размера.
 Nicol Bolas04 авг. 2016 г., 18:09
@ n.m .: Вы всегда можете генерировать данные этого типа с помощью операций, которыене навязать эту кодировку. Набор операций, которые генерируютwchat_t данные не ограничиваются вещами, которые используют глобальный аспект.
 Richard Hodges04 авг. 2016 г., 17:05
wchar_t - это фиаско. действительно должна быть библиотека, делающая обработку строк в юникоде более интуитивно понятной в кроссплатформенном виде ...stackoverflow.com/questions/2722951/...
 Galik04 авг. 2016 г., 16:59
wchar_t это простоспособный содержащий либоUCS2 или жеUCS4 это неуполномочена к.
 n.m.05 авг. 2016 г., 01:35
@KerrekSB «Тип не имеет такой семантики». Произвольная цитата из стандарта: «Универсальное символьное имя переводится в кодировку, в соответствующем наборе символов выполнения, названного символа». Таким образом, может показаться, что в реализации реализовано отображение между именами универсальных символов (== кодовые точки юникода) и целочисленными кодами членов соответствующих наборов символов выполнения (в данном случае == значения wchar_t). Я бы назвал это отображение "кодировка wchar_t", потому что это то, что оно есть.
 Justin Time28 дек. 2016 г., 00:05
Другая интерпретация заключается в том, чтоcodecvt_utf8 а такжеcodecvt_utf16 увидетьwchar_t как UCS2 или UCS4, независимо от того, что видит остальная вселенная.
 Kerrek SB05 авг. 2016 г., 01:51
@ н.м .: это говорит о том, что типwchar_t может быть использован хранить значения набора символов выполнения (которые имеют значение). Он не привязывает этот тип к определенной кодировке. Тип вполне может содержать значения, которые не являются частью набора символов выполнения. Это похоже на то, какchar32_t может содержать все символы в строке UTF-32, но также может содержать значения, которые не являются частью кодировки Unicode. Или, если хотите, какsize_t может содержать размер любого объекта, но не каждое значениеsize_t может быть реализован как размер какого-либо объекта.

Ответы на вопрос(7)

Нет.

wchar требуется только для хранения самой большой локали, поддерживаемой компилятором. Который теоретически мог бы поместиться в символ.

Тип wchar_t - это отдельный тип, значения которого могут представлять разные коды для всех членов наибольшего расширенного набора символов, указанного среди поддерживаемых локалей (22.3.1).

- C ++ [basic.fundamental] 3.9.1 / 5

как таковой, он даже не обязан поддерживать Unicode

Ширина wchar_t зависит от компилятора и может составлять до 8 бит. Следовательно, программы, которые должны быть переносимы на любой компилятор C или C ++, не должны использовать wchar_t для хранения текста Unicode. Тип wchar_t предназначен для хранения широких символов, определенных компилятором, которые могут быть символами Unicode в некоторых компиляторах.

ISO / IEC 10646: 2003 стандарт Юникод 4.0

Решение Вопроса

wchar_t это просто интегральный литерал. У него есть минимальное значение, максимальное значение и т. Д.

Его размер не зафиксирован стандартом.

Если он достаточно велик, вы можете хранить данные UCS-2 или UCS-4 в буфереwchar_t, Это верно независимо от того, в какой системе вы находитесь, поскольку UCS-2 и UCS-4, а также UTF-16 и UTF-32 являются просто описаниями целочисленных значений, упорядоченных в последовательности.

В C ++ 11 естьstd API, которые читают или пишут данные, предполагая, что они имеют эти кодировки. В C ++ 03 есть API, которые читают или записывают данные, используя текущую локаль.

22.5 Стандартные аспекты преобразования кода [locale.stdcvt]

3 Для каждого из трех аспектов преобразования кода codecvt_utf8, codecvt_utf16 и codecvt_utf8_utf16:

(3.1) - Elem - это тип широких символов, например, wchar_t, char16_t или char32_t.

4 Для аспекта codecvt_utf8:

(4.1) - Фасет должен преобразовывать между многобайтовыми последовательностями UTF-8 и UCS2 или UCS4 (в зависимости от размера Elem) в программе.

Так вотcodecvt_utf8_utf16 имеет дело сutf8 с одной стороны, и UCS2 или UCS4 (в зависимости от размера Elem) с другой. Это делает преобразование.

Элем (широкий символ) предполагается закодировать в UCS2 или UCS4 в зависимости от его размера.

Это не значит чтоwchar_t закодирован как таковой, это просто означаетэта операция интерпретируетwchar_t как закодированный как таковой.

То, как UCS2 или UCS4 попали в Elem, не относится к этой части стандарта. Может быть, вы установили это с помощью шестнадцатеричных констант. Может быть, вы читаете это с IO. Может быть, вы рассчитали это на лету. Может быть, вы использовали высококачественный генератор случайных чисел. Может быть, вы сложили битовые значенияascii строка. Может быть, вы рассчитали приближение с фиксированной точкойlog* от количества секунд, которое требуется луне, чтобы изменить день Земли на 1 секунду.Не эти абзацы проблемы. Эти правила просто предписывают, как биты модифицируются и интерпретируются.

Аналогичные претензии имеют место в других случаях. Это не требует, какой форматwchar_t иметь. Это просто заявляет, как эти аспекты интерпретируютwchar_t или жеchar16_t или жеchar32_t или жеchar8_t (чтение или письмо).

Другие способы взаимодействия сwchar_t использовать различные методы, чтобы установить, как значениеwchar_t интерпретируется.

iswalpha использует (глобальную) локаль для интерпретацииwchar_t, например. В некоторых местныхwchar_t может быть UCS2. В других это может быть какая-то безумная ктульская кодировка, детали которой позволяют увидеть новый цвет из космоса.

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

Стандарт C ++ не предписывает, что хранится вwchar_t, Он предписывает, какие определенные операции интерпретируют содержаниеwchar_t быть. В этом разделе описывается, как некоторые аспекты интерпретируют данные вwchar_t.

Давайте различатьwchar_t и строковые литералы, построенные с использованиемL префикс.

wchar_t это просто целочисленный тип, который может быть больше, чемchar.

Строковые литералы, использующиеL префикс будет генерировать строки, используяwchar_t персонажи. То, что это означает, зависит от реализации. Нет необходимости использовать такие литералылюбая конкретная кодировка, Они могут использовать UTF-16, UTF-32 или что-то еще, что вообще не имеет ничего общего с Unicode.

Так что если вы хотите строковый литерал, которыйгарантированный для кодирования в формате Unicode на всех платформах используйтеu8, u, или жеU префиксы для строкового литерала.

Одно из толкований этих двух параграфов состоит в том, что wchar_t должен быть закодирован как UCS2 или UCS4.

Нет, это неверная интерпретация.wchar_t не имеет кодировки; это просто тип. этоданные который закодирован. Строковый литерал с префиксомL может или не может быть закодирован в UCS2 или UCS4.

Если вы предоставитеcodecvt_utf8 строкаwchar_ts, которые закодированы в UCS2 или UCS4 (в зависимости отsizeof(wchar_t)), тогда это будет работать. Но не из-заwchar_t; это работает только потому, чтоданные Вы предоставляете это правильно закодировано.

Если в пункте 4.1 сказано, что «фасет должен преобразовывать между многобайтовыми последовательностями UTF-8 и UCS2 или UCS4 или любым другим кодированием, наложенным на wchar_t текущим глобальным языковым стандартом», то проблем не будет.

Весь смысл этихcodecvt_* Грани, чтобы выполнитьлокаль-независимым преобразования. Если вы хотите конверсии, зависящие от локали, вы не должны их использовать. Вместо этого вы должны использовать глобальныйcodecvt фаска.

 n.m.04 авг. 2016 г., 18:02
«Они накладывают кодировки на определенные операции». Это накладывает кодирование наwchar_t в моей книге. Я строю струны для выполнения операций с ними, а не для их обрамления и повешения на стене. codecvt является аспектом локали, локали простоиметь их.
 Nicol Bolas04 авг. 2016 г., 17:41
@ n.m .: см. правки.
 Justin Time27 дек. 2016 г., 22:52
@ N.m. Согласиться с NicolBolas здесь. Стандарт определяет в п. 3.9.1.5, что «Типwchar_t является отдельным типом, значения которого могут представлять различные коды для всех членов самого большого расширенного набора символов, указанного среди поддерживаемых языковых стандартов "; в то же время это гарантирует, что любая платформа, поддерживающая UTF-32, сможет хранить любую кодовую точку UTF-32 вwchar_tЭто не гарантирует, что любая система, которая поддерживает только, скажем, UTF-8 или UTF-16, сможет.
 Justin Time27 дек. 2016 г., 22:54
Следует также отметить, что Windows явнобрейки это правило, вероятно, для обратной совместимости:wchar_t 16 бит на Windows
 Nicol Bolas04 авг. 2016 г., 18:06
@ n.m .: см. редактировать.
 Justin Time02 янв. 2017 г., 23:57
я знаюcppreference склоняется к # 2, так как они специально упоминают Windows как заметное исключение из правила. Когда я сделал свой комментарий, я, кажется, смешал обе интерпретации, вероятно, потому что я обращался к cppreference при поискеwchar_tСпецификации вверх. Я до сих пор не уверен, что это правильная интерпретация, сам.
 Nicol Bolas27 дек. 2016 г., 23:56
@JustinTime: Но локали стандартной библиотеки VC не поддерживают UTF-32. Вот что дает им свободу ограничиватьwchar_t до 16 бит
 n.m.04 авг. 2016 г., 17:49
Существует одна или несколько кодировокwchar_t различными аспектами локали. Я спрашиваю, должен ли какой-либо из них или все они быть UCS-чем угодно.
 Nicol Bolas04 авг. 2016 г., 17:50
@ n.m .: Нет, навязывают локалиничего такого наwchar_t, Они накладывают кодировки на определенные операции. Таким образом, вы можете создать строку для кодирования с iostream, используя локаль, которая навязывает эту кодировку потоку. Но это не имеет ничего общего с поведениемwchar_t сам; это влияет только на данные, хранящиеся вwchar_t массив. И локали ничего не навязываютcodecvt фасеты.
 Nicol Bolas04 авг. 2016 г., 17:36
@ n.m .: Моя интерпретация этих абзацев такова, что они означают именно то, что говорят. Ваша интерпретация их запутана, потому что ваше понимание слов, которые они используют, запутано. Вот почему я объяснил, что означают эти слова.wchar_t это не кодировка Этоне имеет кодировки; это просто тип.
 Nicol Bolas04 авг. 2016 г., 18:44
@ n.m .: "чтобы иметь возможность конвертировать UTF-8 в wchar_t способом, который согласуется с другими видами использования wchar_t.«Нет способа сделать это, как показанотаблица внизу этой страницы, Не знаяименно так какая кодировка вашегоwchar_t-строки, которые варьируются в зависимости от платформы. "Я знаю, что могу конвертировать UTF-8 в UCS4 и заполнить эти значения в wchar_t«На самом деле, вы не знаете, что вы можете сделать это, так какwchar_t не требуется иметь возможность хранить кодовые точки UTF-32.
 n.m.04 авг. 2016 г., 18:36
Я хочу очень простую вещь, чтобы иметь возможность конвертировать UTF-8 в wchar_t способом, который согласуется с другими использованиями wchar_t. А именно, печать в (без изменений) wcout, сравнение с литералами L "" и / или запрос битов isw ..., не затрагивая мою текущую глобальную локаль или локали потока. Я знаю, что могу преобразовать UTF-8 в UCS4 и поместить эти значения в wchar_t, но это кажется довольно бесполезным упражнением, если только я не узнаю, что упомянутые мной операции действительно используют UCS4.
 Justin Time02 янв. 2017 г., 23:54
@NicolBolas Хм ... кажется, я не уверен на 100%, как интерпретировать эту спецификацию, на самом деле. Из-за этой формулировки существует два возможных способа интерпретации ее относительно Unicode: 1) Каждый UTF-n Вариант Unicode может рассматриваться по-разному, поэтому платформа, поддерживающая UTF-16, требуетwchar_t должно быть не менее 16 бит, но не обязательно 32 бита, или 2) Поскольку символы Unicode могут иметь длину до 32 бит, независимо от того, используете ли вы UTF-8, UTF-16, UTF-32, UCS-2 или UCS-4 ,wchar_t должно быть не менее 32 бит на любой платформе, поддерживающей Unicode.

КакElem может бытьwchar_t, char16_t, или жеchar32_tпункт 4.1 ничего не говорит о необходимомwchar_t кодирование. Это заявляет кое-что о выполненном преобразовании.

Из формулировки ясно, что преобразование происходит между UTF-8 и UCS-2 или UCS-4, в зависимости от размераElem, Так что еслиwchar_t 16 бит, преобразование будет с UCS-2, а если это 32 бита, UCS-4.

Почему в стандарте упоминаются UCS-2 и UCS-4, а не UTF-16 и UTF-32? Так какcodecvt_utf8 преобразует многобайтовый UTF8 в один широкий символ:

UCS-2 является подмножеством юникода, но естьнет кодирования суррогатной пары вопреки UTF-16UCS-4 - это то же самое, что и UTF-32, сейчас (но, учитывая растущее число смайликов, может быть, однажды не хватит 32 бит, и у вас будут суррогатные пары UTF-64 и UTF32, которые бы не будет поддерживатьсяcodecvt_utf8)

Хотя мне не ясно, что произойдет, если текст UTF-8 будет содержать последовательность, соответствующую символу Unicode, который недоступен в UCS-2, используемом для полученияchar16_t.

 n.m.04 авг. 2016 г., 18:44
К вашему последнему утверждению: конвертация просто не удастся ИМО.

Похоже, ваш первый вывод разделяютMicrosoft кто перечисляет возможные варианты и отмечает, что UTF-16, хотя и «широко используется как таковой [sic]», не является допустимой кодировкой.

Та же самая формулировка также используетсяQNX, который указывает на источник формулировки: и QNX, и Microsoft получают свою реализацию Стандартной библиотеки от Dinkumware.

Теперь, как это происходит, Dinkumware также является авторомN2401 который ввел эти классы. Поэтому я собираюсь принять их.

 MSalters04 авг. 2016 г., 17:48
@Holt: этот бит следует за «... несколькими кодировками символов. Для широких символов ...:», за которыми следует список, определяющий UCS2, UCS4 и UTF-16. Нет никаких подсказок, чтобы предположить, что список - просто примеры; это кажется исчерпывающим.
 Holt04 авг. 2016 г., 17:43
Похоже, ваш первый вывод поделился Microsoft - Не могли бы вы уточнить? Единственное, что я могу получить по этой ссылке, это определение UCS- * / UTF- *, а не то, чтоwchar_t должен быть закодирован как UCS-2/4.
 Holt04 авг. 2016 г., 17:52
@MSalters Это единственные, которые появляются в стандарте, поэтому они просто определяют возможную интерпретацию термина в стандарте. По крайней мере, так я это вижу.
 n.m.04 авг. 2016 г., 17:43
Хм, Microsoft говорит: «Представляет аспект локали, который преобразует между широкими символами, закодированными как UCS-2 или UCS-4 ...». Кажется, это не значит, что других возможностей нет. Я помню работу с машинами, где wchar_t был JIS один или другой, такие среды не поддерживаются текущим C ++?

Обе ваши интерпретации неверны. Стандарт не требует наличия единогоwchar_t кодирование, как это не требует ни одногоchar кодирование.codecvt_utf8 фасет должен конвертировать между UTF-8 и UCS-2 или UCS-4. Это правда, даже UTF-8, UCS-2 и UCS-4 не поддерживаются в качестве наборов символов ни в одной локали.

ЕслиElem имеет типwchar_t и недостаточно велик для хранения значения UCS-2, чем для операций преобразованияcodecvt_utf8 фасет не определен, потому что стандарт не говорит, что происходит в этом случае. Если он достаточно большой (или если вы хотите утверждать, что стандарт требует, чтобы он был достаточно большим), то это просто реализация, определяемая как UCS-2 или UCS-4wchar_t значения, которые генерирует или потребляет фасет, находятся в кодировке, совместимой с любой определенной локальюwchar_t кодирование.

 n.m.05 авг. 2016 г., 01:43
Если программист знает, что UCS-2/4 является нативной кодировкой, то моя предложенная «разумная» семантикаcodecvt_utf8<wchar_t> совпадает со стандартной семантикой, и программист может ее использовать. Это когда эта информация не известнаcodecvt_utf8<wchar_t> не имеет смысла.
 Ross Ridge04 авг. 2016 г., 20:50
@ N.m. Ваша вторая интерпретация говорит, чтоcodecvt_utf8 не сработает, еслиwchar_t кодирование не обязательно должно быть UCS2 или UCS4 ". Стандарт не требует"wchar_t кодировка ", что бы вы ни думали, значит быть UCS-2/4, но для этого требуется, чтобыcodecvt_ut8 работать. Можно утверждать, что требования кcodecvt_utf8 предъявлять требования к размеруwchar_t, но они не предъявляют требований к кодировке, используемой чем-либо еще, где-либо еще в стандарте.
 Ross Ridge05 авг. 2016 г., 02:40
@ N.m. Нет, как я сказал, ваше предложение не имеет смысла, потому что оноcodecvt_utf8 зависит от локали. В любом случае, ваш вопрос должен был быть о том, что на самом деле говорит стандарт, а не о том, что будет иметь для вас больше смысла.
 n.m.04 авг. 2016 г., 22:26
В моей книгеcodecvt_utf8<wchar_t> будет работать разумно, если он конвертируется между UTF-8 и роднойwchar_t кодирование (да, я уверен, что мы можем говорить о родномwchar_t кодирование). Преобразование между utf_8 и ucs2 / ucs4 обрабатываетсяcodecvt_utf8<char16_t> а такжеcodecvt_utf8<char32_t>, Зачемcodecvt_utf8<wchar_t> когда-нибудь нужно?
 Ross Ridge05 авг. 2016 г., 01:30
@ N.m. Почему стандарт не должен позволять кому-либо выбиратьwchar_t? Программист может легко знать, что UCS-2/4 является нативной кодировкой. Это не так уж редко, чтобы это было правдой.
 n.m.04 авг. 2016 г., 21:48
«это требует, чтобы codecvt_ut8 работал», возможно, для некоторого определения «работы». Это не требует его работыздраво (то есть способом, совместимым с другими функциями wchar_t; если я преобразуюu"abc"результат не обязательно должен быть равен L "abc", который в моей книге подпадает под "не работает"). Я добавил свой ответ, вы можете комментировать.
 n.m.05 авг. 2016 г., 01:08
Почему кто-то выбралwchar_t хранить данные в кодировке UCS-2/4, если не известно, что UCS-2/4 является его собственной кодировкой? Кажется, чтоchar16_t а такжеchar32_t было бы намного лучше кандидатов.
 n.m.04 авг. 2016 г., 18:47
Я не понимаю, как они могут быть неверными. Мне кажется, что ваш ответ подразумевает, что второй является правильным (если нет, пожалуйста, укажите, где он терпит неудачу).
 n.m.04 авг. 2016 г., 20:23
Честно говоря, я не понимаю, где вторая интерпретация предполагает что-то подобное. Если в некоторой реализации кодировкой wchar_t по умолчанию для любой локали или некоторой определенной локали является UCS4, то, очевидно,codecvt_utf8<wchar_t> будет совместим с этой кодировкой локали. Вопрос заключается в том, требуется ли реализация, чтобы сделать это правдой или нет. Второе толкование говорит: нет, это не так. Но, возможно, это не самый лучший способ.
 Ross Ridge04 авг. 2016 г., 22:12
@ n.m. Мне кажется,codecvt_utf8 действительно работает разумно, так как он разработан для обработки случая, когда программист не может предположить, что другие функции поддерживают UTF-8 и UCS-2/4. Он не предназначен для того, чтобы требовать полной поддержки Unicode в реализациях, просто предоставляет некоторые базовые функциональные возможности в тех случаях, когда программисты хотят использовать Unicode в переносимой программе. Таким образом, это просто альтернатива программистам, пишущим собственный код преобразования, и этого достаточно, чтобы сделать его полезным и разумным.
 Ross Ridge04 авг. 2016 г., 19:46
@ n.m Ваша вторая интерпретация не удалась по двум пунктам. Сначала предполагается, что существует один глобальныйwchar_t кодирование во времени. По умолчанию существует одна локальширокий характер кодирование, но это влияет только на определенные функции локальной зависимой библиотеки. Второйcodecvt_utf8 фасет требуется для преобразования между значениями UCS-2/4 и UTF-8, когдаElem являетсяwchar_t, еслиwchar_t достаточно большой. Еслиwchar_t скажем, 16-бит, тоconvert_utf8/16 аспекты должны конвертироваться между UCS-2, но это не накладывает никаких требований на использование UCS-2.
 Ross Ridge05 авг. 2016 г., 00:04
@ N.m. Для преобразования между UCS-2/4 в кодировкеwchar_t значения независимо от того, какие бывают нативные широкие символьные кодировки. Программы не ограничены использованиемwchar_t с реализацией определены широкие символьные кодировки. В этом отношении они также могут предпочесть, что UCS-2/4 является определенной кодировкой реализации. Было бы неразумно делатьcodecvt_utf8 зависит от локали, поскольку она предназначена для выполнения конкретного преобразования независимо от локали. Функциональность, которую вы ожидаете от нее, должна быть в каком-то другом, зависящем от локали средстве

Первая интерпретация условно верна.

Если__STDC_ISO_10646__ макрос (импортированный из C) определяется, затемwchar_t является надмножеством некоторой версии Unicode.

__STDC_ISO_10646__
Целочисленный литерал видаyyyymmL (например,199712L). Если этот символ определен, то каждый символ в Юникоде должен быть установлен при хранении в объекте типаwchar_t, имеет то же значение, что и короткий идентификатор этого символа. Требуемый набор Unicode состоит из всех символов, определенных ISO / IEC 10646, а также всех поправок и технических исправлений по состоянию на указанный год и месяц.

Похоже, что если макрос определен, можно предположить некоторый тип UCS4. (Не UCS2, так как ISO 10646 никогда не имел 16-битной версии; первый выпуск ISO 10646 соответствует Unicode 2.0).

Так что, если макрос определен, то

есть "родная" кодировка wchar_tэто надмножество какой-то версии UCS4преобразование обеспечиваетсяcodecvt_utf8<wchar_t> совместим с этой нативной кодировкой

Ничего из этого не требуется хранить, если макрос не определен.

Это также__STDC_UTF_16__ а также__STDC_UTF_32__ но стандарт C ++ не говорит, что они имеют в виду. Стандарт C говорит, что они обозначают кодировки UTF-16 и UTF-32 дляchar16_t а такжеchar32_t соответственно, но в C ++ эти кодировки всегда используются.

Кстати, функцииmbrtoc32 а такжеc32rtomb конвертировать назад и вперед междуchar последовательности иchar32_t последовательности. В C они используют UTF-32 только если__STDC_UTF_32__ определяется, но в C ++ UTF-32 всегда используется дляchar32_t, Так что, казалось бы, даже если бы__STDC_ISO_10646__ являетсяне определяется, должно быть возможно конвертировать между UTF-8 иwchar_t переходя от UTF-8 к кодировке UTF-32char32_t в нативном кодированииchar в нативном кодированииwchar_tНо я боюсь этого сложного.

Ваш ответ на вопрос