Спецификаторы исключений устарели, потому что спецификаторы исключений, как правило, ужасная идея. noexcept
был добавлен, потому что это единственное разумно полезное использование спецификатора исключения: знание того, когда функция не генерирует исключение. Таким образом, это становится двоичным выбором: функции, которые будут генерировать и функции, которые не будут выбрасывать.
noexcept
был добавлен вместо того, чтобы просто удалить все спецификаторы выброса, кроме throw()
, потому что noexcept
более мощный. noexcept
может иметь параметр, который во время компиляции преобразуется в логическое значение. Если логическое значение истинно, то noexcept
остается. Если логическое значение ложно, то 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()
будет бросать, если и только если выдает конструктор по умолчанию данного типа. Это устраняет одну из основных проблем со спецификаторами исключений: их неспособность распространяться вверх по стеку вызовов.
Вы не можете этого сделать с throw()
.
person
Nicol Bolas
schedule
11.10.2012
noexcept
могут потребоваться проверки во время выполнения. Основное различие между ними в том, что взломnoexcept
вызываетstd::terminate
, а взломthrow
вызываетstd::unexpected
. Также в этих случаях немного другое поведение при раскручивании стека. - person Fiktik   schedule 11.10.2012