Наследовать от std :: exception без изменения кода пользователя - PullRequest
1 голос
/ 15 марта 2019

В настоящее время в нашем 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 без изменения того, какой обработчик вызовов будет вызываться?

1 Ответ

1 голос
/ 15 марта 2019

Самый безопасный способ - в этом случае изменить тип исключения на новый тип, например, MyExceptionV2, обучить людей, что он намного лучше, и что MyException в конечном итоге будет признано устаревшим.Затем дайте им время обновить свои блоки улова, чтобы использовать ваш новый тип, и уберите лишние блоки улова.Затем устареть в следующей версии, затем удалить MyException в более поздней версии.

...