В настоящее время в нашем API есть наш собственный тип исключения MyException
, который (ни прямо, ни косвенно) не наследуется от std::exception
или любого другого типа:
class MyException {
public:
MyException(std::string const& message);
std::string const& GetErrorMessage() const;
private:
//...stuff, e.g. like the error-message.
};
Для наших клиентов (и наших собственных разработчиков) это приводит к бремени добавления как минимум двух обработчиков catch к блоку try:
try {
SomeLibraryFunction();
}
catch (MyException const& e) { std::cerr << e.GetErrorMessage(); }
catch (std::exception const& e) { std::cerr << e.what(); }
Чтобы уменьшить количество обработчиков catch, я бы хотел добавить наследование от std::exception
. Но проблема в том, что он «сломает» существующий код. А именно, компилятор выберет другой обработчик catch, чем он делал раньше:
try {
SomeOtherLibraryFunction();
}
catch(std::exception const& e) { std::cerr << "STD-EX"; }
catch(MyException const& e)
{
std::cerr << "LIBRARY-EX";
ExecuteMandatoryCodeWhenMyExceptionGetsThrown(e);
}
Как только MyException
наследует от std::exception
, второй обработчик catch никогда не будет достигнут. Причина этого указана здесь :
Когда исключение типа E генерируется любым оператором в составном операторе, оно сопоставляется с типами формальных параметров T каждого предложения catch в handler-seq в порядке, в котором перечислены предложения catch .
Есть ли способ, которым компилятор примет предложение catch, которое является лучшим соответствием, вместо первого соответствия? Или каким-либо другим способом получить наследование от std::exception
без изменения того, какой обработчик вызовов будет вызываться?