Разница между С++ 03 throw() specifier С++ 11 noexcept

Есть ли другое отличие между throw() и noexcept от проверки времени выполнения и времени компиляции соответственно?

Wikipedia С++ 11 статья предполагает, что спецификаторы броска С++ 03 устарели.
Почему так, noexcept способен достаточно охватить все, что во время компиляции?

[Примечание: я назвал этот вопрос и в этой статье, но не смог " t получил твердую причину устаревания.]

Ответ 1

Спецификаторы исключений были устаревшими, поскольку спецификаторы исключений, как правило, представляют собой ужасную идею. noexcept был добавлен, потому что это одно полезное использование спецификатора исключения: зная, когда функция не будет генерировать исключение. Таким образом, он становится двоичным выбором: функции, которые будут бросать, и функции, которые не будут выбрасываться.

noexcept, а не просто удаление всех спецификаторов throw, отличных от throw(), потому что noexcept более мощный. noexcept может иметь параметр, который время компиляции разрешается в логическое. Если логическое значение истинно, то 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().

Ответ 2

noexcept не проверяется во время компиляции.

Реализация не должна отвергать выражение только потому, что при его выполнении он генерирует или может вызывать исключение, которое не допускает содержащая функция.

Когда функция, объявленная noexcept или throw(), пытается создать исключение, единственное отличие состоит в том, что вы вызываете terminate и othe вызовы unexpected, а последний стиль обработки исключений эффективно устарел.

Ответ 3

std:: unexpected() вызывается средой выполнения С++ при нарушении динамической спецификации исключения: исключение выбрано из функции, спецификация исключений которой запрещает исключения этого типа.

std:: неожиданный() также может быть вызван непосредственно из программы.

В любом случае std:: неожиданно вызывает установленный в настоящий момент std:: неожиданный_handler. По умолчанию std:: unexpected_handler вызывает std:: terminate.