Как я вижу в cppreference, Классические списки объявлений throw теперь устарели в C ++ 11. Какова причина выхода из этого механизма, и как я должен указать, какие исключения вызывает мою функцию?
Для более подробного объяснения см .: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html
Как указано в комментарии национального органа выше, спецификации исключений не оказались полезными на практике. Существует множество обсуждений проблем со спецификациями исключений в C ++ (см., Например, [Sutter02], [Boost03]), но основными проблемами являются:
- Проверка во время выполнения: спецификации исключений C ++ проверяются во время выполнения, а не во время компиляции, поэтому они не дают программисту гарантий того, что все исключения были обработаны. Режим сбоя во время выполнения (вызов std :: surprise ()) не поддается восстановлению.
- Затраты времени выполнения: проверка времени выполнения требует, чтобы компилятор генерировал дополнительный код, который также препятствует оптимизации.
- Неприменимо в универсальном коде: в универсальном коде, как правило, невозможно узнать, какие типы исключений могут быть вызваны операциями над аргументами шаблона, поэтому точная спецификация исключений не может быть написана.
На практике полезны только две формы гарантий создания исключений: операция может выдать исключение (любое исключение) или операция никогда не вызовет исключение. Первое выражается посредством полного исключения спецификации исключения, а второе может быть выражено как throw (), но редко из-за соображений производительности.
[N3050] вводит новый тип спецификации исключений, noexcept, указывает, что функция не будет генерировать никаких исключений. В отличие от throw (), noexcept не требует, чтобы компилятор вводил код для проверки, генерируется ли исключение. Скорее, если функция, указанная как noexcept, завершается через исключение, результатом является вызов std :: terminate ().С введением noexcept теперь программисты могут выражать два вида исключительных гарантий, которые полезны на практике, без дополнительных накладных расходов. Поэтому в этой статье предлагается отказаться от спецификаций «динамических» исключений, то есть тех, которые записываются как throw (type-id-listopt).
Ответ Питера не затрагивает актуальную проблему спецификаций исключений для разработчика и пользователя:
Вывод заключается в том, что C ++ должен был пойти тем же путем, что и Java:
Noexcept (начиная с C ++ 11) страдает той же концептуальной ошибкой, так как это также вызовет завершение во время выполнения, если спецификация тоже не соблюдается, то есть метод выбрасывает, который был объявлен как not. Это делает noexcept
невозможно использовать для чего-либо серьезного, но в большинстве случаев (на ум приходят конструкторы).
Они производят медленный и больший код, потому что libc ++ должен проверить, нарушает ли какое-либо исключение, распространяющееся из функции, его спецификацию исключения и вызов std::unexpected
, Это вряд ли когда-либо полезно и хуже, чем просто документирование исключений, которые выдает сама функция.
Только форма без списка бросить () устарела. Формы без пропущенного списка бросить (int, исключение&), и т.д. не являются устаревшими.