Подтвердить что ты не робот

Если вы поймаете исключение по ссылке, можете ли вы изменить его и реконструировать?

Есть ли в стандарте что-нибудь сказать об исключении, которое поймано ссылкой и что происходит с попытками его изменить?

Рассмотрим следующий код:

class my_exception: public std::logic_error
{
public:
    std::vector<std::string> callstack;
};

void MyFunc()
{
    try
    {
        SomethingThatThrows();
    }
    catch (my_exception & e)
    {
        e.callstack.push_back("MyFunc");
        throw;
    }
}

Это надуманный пример, я на самом деле не пытаюсь что-то вроде этого. Мне было просто любопытно, что произойдет, основываясь на предположении в другом потоке, что исключения должны быть пойманы ссылкой const.

4b9b3361

Ответ 1

Исключение будет изменено.

§15.3 [except.handle]/17:

Когда обработчик объявляет непостоянный объект, любые изменения этого объекта не будут влиять на временные  объект, который был инициализирован выполнением выражения throw.

Когда обработчик объявляет ссылку на непостоянный объект, любые изменения ссылочного объекта являются изменениями в инициализированном временном объекте когда выражение throw было выполнено и будет иметь эффект, чтобы этот объект был сброшен.

Итак, если my_exception поймано вне MyFunc, мы увидим запись "MyFunc" в стоп-кадре (например, http://ideone.com/5ytqN)

Ответ 2

Да, вы можете это сделать.

Когда вы удаляете текущее исключение с помощью throw;, копии не выполняются: исходный объект временного исключения повторно завершается. Таким образом, любые изменения, которые вы вносите в этот объект в обработчике, будут присутствовать в объекте исключения, когда вы его поймаете.