Почему требуется wchar_t
? Как он превосходит short
(или __int16
или что-то еще)?
(Если это имеет значение: я живу в мире Windows. Я не знаю, что Linux делает для поддержки Unicode.)
Почему требуется wchar_t
? Как он превосходит short
(или __int16
или что-то еще)?
(Если это имеет значение: я живу в мире Windows. Я не знаю, что Linux делает для поддержки Unicode.)
Почему нужен wchar_t? Как он превосходит короткий (или __int16 или что-то еще)?
В мире С++ wchar_t
- это собственный тип (я думаю, что это a typedef
в C), поэтому вы можете перегружать функции на основе этого. Например, это позволяет выводить широкие символы, а не выводить их числовое значение. В VC6, где wchar_t
был всего лишь typedef
для unsigned short
, этот код
wchar_t wch = L'A'
std::wcout << wch;
выводит 65
, потому что
std::ostream<wchar_t>::operator<<(unsigned short)
. В новых версиях VC wchar_t
- это отдельный тип, поэтому
std::ostream<wchar_t>::operator<<(wchar_t)
вызывается A
.
См. Wikipedia.
В принципе, это переносимый тип для "текста" в текущей локали (с умляутами). Он предшествует Unicode и не решает много проблем, поэтому сегодня он в основном существует для обратной совместимости. Не используйте его, если вам не нужно.
Причина в том, что a wchar_t
по той же причине существует size_t
или time_t
- это абстракция, которая указывает, какой тип предназначен для представления, и позволяет реализациям выбирать базовый тип, который может представлять собой типа на конкретной платформе.
Обратите внимание, что wchar_t
не обязательно должен быть 16-разрядным типом - есть платформы, где 32-разрядный тип.
Обычно считается хорошей вещью, чтобы давать такие вещи, как типы значимых имен данных.
Что лучше, char или int8? Я думаю это:
char name[] = "Bob";
гораздо легче понять, чем это:
int8 name[] = "Bob";
Это то же самое с wchar_t и int16.
Когда я прочитал соответствующие стандарты, похоже, что Microsoft сильно исправила это.
Моя управляющая страница для POSIX <stddef.h>
говорит, что:
- wchar_t: целочисленный тип, диапазон значений которого может представляют собой различные широкозначные коды для всех членов самого большого набора символов, указанного среди локали, поддерживаемые средой компиляции: null символ имеет значение 0 и каждый элемент переносимого набора символов имеет значение кода, равное его значение при использовании в качестве одиночного символа целочисленного символа постоянная.
Итак, 16 бит wchar_t недостаточно, если ваша платформа поддерживает Unicode. Каждый wchar_t должен быть отличным значением для персонажа. Поэтому wchar_t - это полезный способ работать на уровне символов текстов (после декодирования из многоуровневого языка, конечно), чтобы быть совершенно бесполезным на платформах Windows.
wchar_t
- это примитив для хранения и обработки символов юникода платформы. Его размер не всегда 16 бит. В Unix-системах wchar_t
- 32 бит (возможно, пользователи unix с большей вероятностью будут использовать klingon charaters, что дополнительные биты используются для: -).
Это может создавать проблемы для переноса проектов, особенно если вы меняете wchar_t
и короткие, или если вы меняете wchar_t
и xerces 'XMLCh
.
Поэтому наличие wchar_t
как другого типа для короткого замыкания очень важно для написания кросс-платформенного кода. Очистка это была одна из самых сложных частей переноса нашего приложения на unix, а затем с VC6 на VC2005.
Чтобы добавить комментарий к Aaron - в С++ 0x мы, наконец, получаем реальные Unicode char типы: char16_t и char32_t, а также строковые литералы Unicode.
Он "превосходит" в некотором смысле, что он позволяет разделить контексты: вы используете wchar_t
в контекстах символов (например, строки), и используете short
в числовых контекстах (числах). Теперь компилятор может выполнить проверку типов, чтобы помочь вам поймать ситуации, когда вы ошибочно смешиваете один с другим, например, передайте абстрактный нестроковый массив short
в функцию обработки строк.
Как сторона node (так как это был вопрос C), в С++ wchar_t
вы можете перегружать функции независимо от short
, т.е. снова предоставлять независимые перегрузки, которые работают со строками и числами (например).
wchar_t немного похмелье от стандартизации уникода. К сожалению, это не очень полезно, потому что кодирование является специфичным для платформы (и для Solaris, специфичного для локали!), А ширина не указана. Кроме того, нет никаких гарантий того, что грани utf-8/16/32 codecvt будут доступны, или как вы будете обращаться к ним. В общем, это немного кошмар для портативного использования.
По-видимому, С++ 0x будет поддерживать юникод, но при нынешних темпах прогресса, которые могут никогда не произойти...
За исключением небольшого японского меньшинства ISO 2022, wchar_t всегда будет unicode. Если вы действительно беспокоитесь, вы можете убедиться в этом во время компиляции:
#ifndef __STDC_ISO_10646__
#error "non-unicode wchar_t, unsupported system"
#endif
Иногда wchar_t - 16 бит UCS-2, иногда 32 бит UCS-4, так что? Просто используйте sizeof(wchar_t)
. wchar_t НЕ предназначен для отправки на диск или в сеть, он предназначен только для использования в памяти.
См. также Следует ли считать UTF-16 вредным? на этом сайте.