Ответ 1
Из N4296 (первый черновик после финального С++ 14) [15.1p3]:
Бросание копии исключения инициализирует (8.5, 12.8) временный объект, называемый объектом исключения. Временной является значением lvalue и используется для инициализации переменной, объявленной в соответствующем обработчике (15.3).
Поэтому вы не можете предположить, что ваш временный "выживает бросок". Если вы выбрали, конструктор копирования объекта исключения типа std::exception
будет вызываться с e
в качестве аргумента. Временное ограничение e
будет уничтожено, когда управление оставляет полное выражение, содержащее вызов my_assert
(либо после нормального возврата, либо как часть разворачивания стека, поскольку вы условно выбрасываете исключение).
Есть обстоятельства, когда копирование объекта исключения может быть отменено, но это не один из них, согласно [12.8p31.2]:
- в выражении throw (5.17), когда операнд - это имя энергонезависимый автоматический объект (кроме функции или catch-clause параметр), объем которого не выходит за пределы самого внутреннего включающий try-block (если есть), операция копирования/перемещения из операнд к объекту исключения (15.1) может быть опущен построение автоматического объекта непосредственно в объект исключения
(акцент мой)