Ответ 1
Вы должны поймать ссылку const lvalue (2):
try { throw std::exception{"what"}; }
catch (const std::exception& ex) {}
Обоснование:
В С++ 11 возможно (с помощью shared_future
), что два потока могут одновременно разматывать одно и то же исключение. Это может произойти в вашем коде, даже если вы не знаете о shared_future
, если вы не управляете всем приложением.
Если два потока пойманы, разматывая одно и то же исключение одновременно, и один или оба потока изменяют исключение, тогда у вас есть условие гонки.
Итак, до тех пор, пока вам не нужно модифицировать объект исключения в предложении catch, пусть компилятор принудительно применяет эту политику для вас - catch by const&
. Если вам действительно нужно изменить исключение, сделайте его копию, измените копию и выбросите копию. Вы можете сделать это, поймав по значению, если вы уверены, что это не будет срезать ваш объект исключения (что обычно не так, если вы ловите std::exception
).