Ответ
Выражение throw; без аргументов используется только внутри обработчика catch для повторной генерации (rethrow) текущего перехваченного исключения. Это позволяет частично обработать исключение (например, залогировать, освободить ресурс) и затем передать его дальше по стеку вызовов для полноценной обработки.
Ключевое отличие от throw e;:
try {
throw std::runtime_error("Original error");
} catch (std::exception& e) {
e = std::runtime_error("Modified"); // Модифицируем ссылку на объект исключения
// throw e; // Бросит КОПИЮ объекта типа std::exception (срезка!), с сообщением "Modified"
throw; // Бросит ИСХОДНОЕ исключение типа std::runtime_error, с сообщением "Original error"
}
Практический пример (логирование с последующей передачей):
void riskyOperation() {
try {
// ... код, который может бросить различные исключения
someLowLevelFunction();
}
catch (...) {
// Логируем факт ошибки на этом уровне, но не знаем, как её обработать
std::cerr << "[ERROR] Exception in riskyOperation() at " << __LINE__ << std::endl;
// Освобождаем критический ресурс, если нужно
releaseResource();
// Передаём исключение наверх, сохраняя его оригинальный тип и состояние
throw;
}
}
Важно: throw; вне блока catch приводит к неопределенному поведению (вызову std::terminate).