Как написать фасет std:: codecvt?

Как написать фасет std:: codecvt? Я бы хотел написать те, которые идут от UTF-16 до UTF-8, которые идут от UTF-16 до текущей текущей кодовой страницы систем (Windows, так CP_ACP) и к кодовой странице OEM-системы (Windows, поэтому CP_OEM).

Предпочтительна кросс-платформа, но MSVC на Windows тоже прекрасен. Существуют ли какие-либо учебные пособия или что-то в этом роде о том, как правильно использовать этот класс?

Ответы

Ответ 1

Я написал один на основе iconv. Его можно использовать в окнах или на любой ОС POSIX. (Вам нужно будет связать с iconv, очевидно).

Наслаждайтесь

Ответ на вопрос "как" заключается в следующем: ссылка codecvt. Еще два года назад я не смог найти лучшие инструкции в Интернете.

Важные замечания

  • теоретически нет необходимости в такой работе. codecvt_byname должно быть достаточно на любой стандартной поддерживающей платформе. Но на самом деле есть некоторые компиляторы, которые не поддерживают или плохо поддерживают этот класс. Существует также различие в интерфейсах codecvt_byname для разных компиляторов.
  • мой рабочий пример реализован с параметром шаблона состояния codecvt. Всегда используйте стандартный тип mbstate, так как это единственный способ использовать ваш codecvt со стандартными классами iostream.
  • std:: mbstate_t не может использоваться как указатель на 64-битных платформах межплатформенным способом.
  • Преобразование stateless работает для коротких строк, но может потерпеть неудачу, если вы попытаетесь преобразовать кусок данных, превышающий размер внутреннего буфера streambuf (UTF - это, по сути, кодирование с сохранением состояния).

Ответ 2

Проблема с этим std:: codecvt - это решение, ищущее проблему. Вернее, проблема, которую она пытается решить, неразрешима, поэтому любой, кто пытается использовать ее в качестве решения, будет очень разочарован.

Если вы не знаете, какой символ задает ваш вход или выход, тогда std:: codecvt никогда не сможет вам помочь. И наоборот, если вы знаете, какие наборы символов вы используете, вы можете тривиально конвертировать между ними с помощью одного вызова функции. Обтекание вызова этой функции сложным беспорядком шаблонов не изменяет эти основы.

... и поэтому никто не использует std:: codecvt. Я рекомендую вам просто делать то, что делают все остальные, и притворяться, что этого не произошло.