Какой тип я должен уловить, если я напишу строковый литерал?
Я пишу довольно простое приложение на С++, используя g++ под Linux, и я пытаюсь перебросить некоторые исходные строки в качестве исключений (да, я знаю, это не очень хорошая практика).
У меня есть следующий код (упрощенный):
int main()
{
try
{
throw "not implemented";
}
catch(std::string &error)
{
cerr<<"Error: "<<error<<endl;
}
catch(char* error)
{
cerr<<"Error: "<<error<<endl;
}
catch(...)
{
cerr<<"Unknown error"<<endl;
}
}
И я получаю Unknow error
на консоли. Но если я статирую буквенную строку для std::string или char *, она печатает Error: not implemented
, как и ожидалось. Мой вопрос: так, какой тип я должен поймать, если я не хочу использовать статические приведения?
Ответы
Ответ 1
Вам нужно поймать его char const*
вместо char*
. Ничто вроде std::string
и char*
не поймает его.
В Catching есть ограниченные правила в отношении того, с какими типами они совпадают. Спектр говорит (где "cv" означает "const/volatile combination" или ни один из них).
Обработчик - это соответствие для объекта исключения типа E, если
Строковый литерал имеет тип char const[N]
, но бросание массива будет распадать массив и на самом деле бросает указатель на его первый элемент. Таким образом, вы не можете поймать поток строк с текстом char*
, потому что в то время, когда он совпадает, ему нужно сопоставить char*
с char const*
, который отбрасывает const (преобразование квалификации разрешено добавлять только Const). Специальное преобразование строкового литерала в char*
рассматривается только тогда, когда вам нужно специально преобразовать строковый литерал.
Ответ 2
Попробуйте добавить const
к типам, которые вы ловите, const char*
(возможно const char* const
).
Ответ 3
Точный тип строкового литерала - это массив константных символов (const char [15]
для вашего примера, поскольку включен терминатор NUL).
Ответ 4
Тип должен быть const char[15]
или const char*
.
Однако, хотя язык не запрещает вам бросать какое-либо значение типа, вы не должны воспитывать собственные типы данных в качестве исключения. Вместо этого вы хотите создать экземпляр std::exception()
или создать свой собственный класс исключений.
Ответ 5
Проблема в том, что вы пытаетесь поймать что-то, что является константой. Будет работать следующее:
catch (const char * ошибка) { сегг
Ответ 6
Тип строкового литерала char const *
. Там (устаревшее) преобразование в char *
предусмотрено для обратной совместимости с существующим кодом (но вы все равно должны рассматривать его как const
- любая попытка модификации дает UB).
Как таковой, такой код должен работать:
#include <iostream>
using namespace std;
int main()
{
try
{
throw "not implemented";
}
catch(char const *error)
{
cerr<<"Error: "<<error<<endl;
}
return 0;
}
Ответ 7
Ознакомьтесь с разделом 2.14.5 стандартной спецификации, он рассматривает типы и виды строковых литералов на 3 страницах. Не делайте то, что вы начали делать, просто скажите:
throw std::exception("not implemented");
вместе с собственным
catch (std::exception& pEx)
Что-то не так с этим "нормальным" подходом...?