Ответ 1
char
предназначен для 8-разрядных кодовых блоков, char16_t
предназначен для 16-разрядных кодовых блоков, а char32_t
- для 32-разрядных кодовых блоков. Любой из них может использоваться для "Unicode"; UTF-8 использует 8-битные кодовые единицы, UTF-16 использует 16-битные кодовые единицы, а UTF-32 использует 32-битные кодовые единицы.
Гарантия на wchar_t
заключалась в том, что любой символ, поддерживаемый в локали, может быть преобразован из char
в wchar_t
, и любое представление, используемое для char
, будь то несколько байтов, коды сдвига, что вы, wchar_t
будет единственным, отличным значением. Целью этого было то, что тогда вы могли бы манипулировать строками wchar_t
так же, как простые алгоритмы, используемые с ASCII.
Например, преобразование ascii в верхний регистр выглядит следующим образом:
auto loc = std::locale("");
char s[] = "hello";
for (char &c : s) {
c = toupper(c, loc);
}
Но это не будет обрабатывать преобразование всех символов в UTF-8 в верхний регистр или все символы в другой кодировке, например Shift-JIS. Люди хотели иметь возможность интернационализировать этот код следующим образом:
auto loc = std::locale("");
wchar_t s[] = L"hello";
for (wchar_t &c : s) {
c = toupper(c, loc);
}
Таким образом, каждый wchar_t
является "символом", и если он имеет версию в верхнем регистре, он может быть напрямую преобразован. К сожалению, это не работает все время; Например, на некоторых языках существуют такие странности, как немецкая буква ß, где верхняя версия на самом деле представляет собой два символа SS вместо одного символа.
Таким образом, интернационализированная обработка текста по своей сути сложнее, чем ASCII, и не может быть действительно упрощена в том, как предназначены дизайнеры wchar_t
. Как таковые wchar_t
и широкие символы вообще не имеют большого значения.
Единственная причина для их использования заключается в том, что они были испечены в некоторых API и платформах. Тем не менее, я предпочитаю придерживаться UTF-8 в своем собственном коде даже при разработке на таких платформах и просто конвертировать на границах API любую кодировку.