Я бы пошел за представление UTF16 в памяти и UTF-8 или 16 на жесткий диск или провод. Основная причина: UTF16 имеет фиксированный размер для каждой «буквы». Это упрощает многие обязанности при работе со строкой (поиск, замена деталей, ...).
Единственная причина для UTF-8 - ограниченное использование памяти для "западных / латинских" букв. Вы можете использовать это представление для хранения на диске или транспортировки по сети. Это также дает то преимущество, что вам не нужно беспокоиться о порядке следования байтов при загрузке / сохранении на диск / провод.
Учитывая эти причины, я бы выбрал внутренний std :: wstring или - если ваша библиотека графического интерфейса предлагает Widestring, используйте его (например, QString из QT). А для хранения на диске я бы написал небольшую независимую от платформы оболочку для платформы API. Или я бы проверил unicode.org, если у них есть платформо-зависимый код, доступный для этого преобразования.
для уточнения: корейские / японские буквы НЕ являются западными / латинскими. Японцы для примера кандзи. Вот почему я упомянул латинский набор символов.
для UTF-16, не являющегося 1 символом / 2 байта. Это предположение верно только для символов, находящихся на базовой многоязычной плоскости (см .: http://en.wikipedia.org/wiki/UTF16). Тем не менее большинство пользователей UTF-16 предполагают, что все символы находятся на BMP. Если это не может быть гарантировано для вашего приложения, вы может переключиться на UTF32 или UTF8.
Тем не менее UTF-16 используется по причинам, упомянутым выше во многих API (например, Windows, QT, Java, .NET, wxWidgets)