Очень частичный ответ на первый вопрос: файл представляет собой последовательность байтов, поэтому при работе с wchar_t
необходимо не менее некоторое преобразование между wchar_t
и char
должно произойти. Чтобы сделать это преобразование «разумным», требуется знание кодировок символов, поэтому это преобразование может быть зависимым от локали в силу использования фасета в локали потока.
Тогда возникает вопрос, как сделать это преобразование в единственной локали, требуемой стандартом: «классической». На это нет «правильного» ответа, и поэтому стандарт очень расплывчат в этом. Из вашего вопроса я понимаю, что вы предполагаете, что слепое приведение (или memcpy () - ing) между wchar_t [] и char [] было бы хорошим способом. Это не является необоснованным, и фактически является тем, что (или, по крайней мере, было) сделано в некоторых реализациях.
Еще одно POV может заключаться в том, что поскольку codecvt является аспектом языкового стандарта, разумно ожидать, что преобразование будет выполнено с использованием «кодирования языкового стандарта» (здесь я неуклюжий, поскольку концепция довольно размыта). Например, можно ожидать, что турецкий язык будет использовать ISO-8859-9, или японец, который будет использовать Shift JIS. По схожести, «классическая» локаль конвертируется в эту «кодировку локали». Очевидно, Microsoft решила просто урезать (что приводит к IS-8859-1, если мы предполагаем, что wchar_t
представляет UTF-16 и что мы остаемся в основной многоязычной плоскости), в то время как реализация Linux, о которой я знаю, решила придерживаться ASCII.
Ваш второй вопрос:
Кроме того, мы получим реальные потоки Unicode с C ++ 0x или я что-то здесь упускаю?
В разделе [locale.codecvt] n2857 (последний имеющийся у меня проект C ++ 0x) можно прочитать:
Специализация codecvt<char16_t, char, mbstate_t>
преобразует схемы кодирования UTF-16 и UTF-8, а специализация codecvt <char32_t, char, mbstate_t>
преобразует схемы кодирования UTF-32 и UTF-8. codecvt<wchar_t,char,mbstate_t>
конвертирует между собственными наборами символов для узких и широких символов.
В разделе [locale.stdcvt] мы находим:
Для фасета codecvt_utf8
:
- Фасет должен преобразовывать между многобайтовыми последовательностями UTF-8 и UCS2 или UCS4 (в зависимости от размера Elem) в программе.
[...]
Для фасета codecvt_utf16
:
- Фасет должен преобразовывать между многобайтовыми последовательностями UTF-16 и UCS2 или UCS4 (в зависимости от размера Elem) в программе.
[...]
Для фасета codecvt_utf8_utf16
:
- Фасет должен преобразовывать между многобайтовыми последовательностями UTF-8 и UTF-16 (один или два 16-битных кода) в программе.
Так что я предполагаю, что это означает «да», но вам нужно быть более точным в том, что вы подразумеваете под «реальными потоками Юникода», чтобы быть уверенным.