Возвращение UTF-8 является очевидным выбором.Если приложение, использующее ваши исключения, использует другую многобайтовую кодировку, может возникнуть проблема с отображением строки.(Он не может знать, что это UTF-8, не так ли?) С другой стороны, для ISO-8859- * 8-битных кодировок (западноевропейский, кириллический и т. Д.) Отображение строки UTF-8 будет "просто" отображать некоторую тарабарщинуи вам (или вашему пользователю) может быть хорошо с этим, если вы не можете устранить неоднозначность между прочим.символ * в наборе символов локали и UTF-8.
Лично я думаю, что только сообщения об ошибках низкого уровня должны идти в строки what (), и лично я думаю, что они все равно должны быть английскими.(Возможно, в сочетании с некоторым номером ошибки или еще чем-то подобным.)
Худшая проблема, с которой я сталкиваюсь при what()
, заключается в том, что в сообщение what () нередко включаются некоторые контекстные детали, например имя файла .Имена файлов не ASCII довольно часто, поэтому у вас не остается иного выбора, кроме как использовать UTF-8 в качестве кодировки what()
.
Обратите также внимание на то, что ваш класс исключений (который получен из std:: исключение), очевидно, может предоставить любые методы доступа, которые вам нравятся, поэтому имеет смысл добавить явный what_utf8()
или what_utf16()
или what_iso8859_5()
.
Редактировать: Относительно комментария Джона о том, какчтобы вернуть UTF-8:
Если у вас есть функция const char* what()
, эта функция, по сути, возвращает набор байтов.На западноевропейской платформе Windows эти байты обычно кодируются как Win1252 , но в русских окнах это также может быть Win1251 .
Что возвращают байтыЗначение зависит от их кодировки, а их кодирование зависит от того, откуда они «пришли» (и кто их интерпретирует).Кодировка строкового литерала определяется во время компиляции, но во время выполнения все еще зависит от приложения, как их интерпретировать.
Итак, чтобы ваше исключение возвращало строки UTF-8 с what()
(или what_utf8()
) вы должны убедиться, что:
- Входное сообщение для вашего исключения имеет четко определенную кодировку
- У вас есть четко определенная кодировка для строкового члена, который вы используете для хранения сообщения.
- Вы соответствующим образом конвертируете кодировку, когда вызывается
what()
Пример:
struct MyExc : virtual public std::exception {
MyExc(const char* msg)
: exception(msg)
{ }
std::string what_utf8() {
return convert_iso8859_1_to_utf8( what() );
}
};
// In a ISO-8859-1 encoded source file
const char* my_err_msg = "ISO-8859-1 ... äöüß ...";
...
throw MyExc(my_err_msg);
...
catch(MyExc const& e) {
std::string iso8859_1_msg = e.what();
std::string utf_msg = e.what_utf8();
...
Преобразование также может быть помещено в (переопределено) то, что() функция-член MyExc () или , вы можете определить исключение, которое будет принимать уже закодированную строку UTF-8 или , которую вы можете преобразовать (из ожидаемой входной кодировки, может быть, wchar_t / UTF-16) в ктор.