Разница между спецификатором c++03 throw() C++11 noexcept
есть ли разница между throw() и noexcept помимо проверки времени выполнения и времени компиляции соответственно ?
Википедия C++11 статья предполагает, что спецификаторы броска C++03 устарели.
Почему так noexcept достаточно способный, чтобы покрыть все это во время компиляции ?
[Примечание: я говорил этот вопрос и в этой статье, но не мог получить твердую причину осуждения.]
3 ответов:
спецификаторы исключений были устаревшими, потому что спецификаторы исключений, как правило, ужасная идея.
noexceptбыл добавлен, потому что это одно разумно полезное использование спецификатора исключений: зная, когда функция не бросать исключение. Таким образом, это становится двоичным выбором: функции, которые будут бросать и функции, которые не будут бросать.
noexceptбыл добавлен вместо того, чтобы просто удалить все спецификаторы броска, кромеthrow(), потому чтоnoexceptis более мощный.noexceptможет иметь параметр, который во время компиляции разрешается в логическое значение. Если логическое значение равно true, тоnoexceptпалочки. Если логическое значение равно false, тоnoexceptне прилипает и функция может бросить.таким образом, вы можете сделать что-то вроде этого:
struct<typename T> { void CreateOtherClass() { T t{}; } };тут
CreateOtherClassисключения? Может быть, еслиT'конструктор по умолчанию можно. Как мы можем сказать? Вот так:struct<typename T> { void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; } };таким образом,
CreateOtherClass()будет бросать iff данного типа конструктор по умолчанию бросает. Это устраняет одну из основных проблем со спецификаторами исключений: их неспособность распространяться вверх по стеку вызовов.вы не можете сделать это с помощью
throw().
noexceptне проверяется во время компиляции.реализация не должна отклонять выражение только потому, что при выполнении оно вызывает или может вызвать исключение, которое не позволяет содержащая функция.
когда функция, которая объявлена
noexceptилиthrow()попытки бросить исключение, единственная разница заключается в том, что один называетterminateа другой зоветunexpectedи последний стиль обработки исключений фактически не одобрять.
std:: unexpected() вызывается средой выполнения C++ при нарушении спецификации динамического исключения: исключение создается из функции, спецификация исключения которой запрещает исключения этого типа.
std:: unexpected() также может быть вызван непосредственно из программы.
в любом случае std::unexpected вызывает установленный в данный момент std::unexpected_handler. По умолчанию std::unexpected_handler вызывает std:: terminate.
Comments