Если вы поймали исключение по ссылке, можете ли вы изменить его и выбросить? - PullRequest
20 голосов
/ 13 декабря 2011

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

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

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 .

Ответы [ 2 ]

20 голосов
/ 13 декабря 2011

Исключение изменится.

§15.3 [except.handle] / 17:

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

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

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

).
10 голосов
/ 13 декабря 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...